Compare commits
95 Commits
e54c99aaff
...
66cac2e12b
| Author | SHA1 | Date |
|---|---|---|
|
|
66cac2e12b | |
|
|
c53b43ee0f | |
|
|
cf69f6e32b | |
|
|
c6b9a0af3d | |
|
|
3dba7fbf84 | |
|
|
2f868ac992 | |
|
|
72841aeaa2 | |
|
|
93fb3dac4a | |
|
|
03e5ce1441 | |
|
|
f8e0a62fba | |
|
|
81911402ce | |
|
|
1e08408cde | |
|
|
0f7291e018 | |
|
|
fefd7d6acf | |
|
|
3626296357 | |
|
|
df45313e15 | |
|
|
330cb8e74d | |
|
|
e7254abd7d | |
|
|
2b62e81a73 | |
|
|
55dd139eda | |
|
|
976501a7d4 | |
|
|
eb28d32081 | |
|
|
176fe49cf0 | |
|
|
edd01f055a | |
|
|
7b25acebc3 | |
|
|
f19f5cc49d | |
|
|
285368e375 | |
|
|
f1f618740d | |
|
|
753dd92013 | |
|
|
34652e500d | |
|
|
2aeadda529 | |
|
|
38cc185319 | |
|
|
a794435ae9 | |
|
|
4af1d7a8b7 | |
|
|
2ed905dc03 | |
|
|
1d358a2061 | |
|
|
72b178950d | |
|
|
3a3e45823d | |
|
|
d457364d1d | |
|
|
9af98c2bfd | |
|
|
297b317850 | |
|
|
b1ef48849c | |
|
|
2cb9b7fcaa | |
|
|
fa18d3a292 | |
|
|
f6b89ec315 | |
|
|
99959fa2fb | |
|
|
66ec5893d7 | |
|
|
6d4ea47541 | |
|
|
94731a80d7 | |
|
|
f441ad6625 | |
|
|
10c77ec6b0 | |
|
|
6182d13091 | |
|
|
8e1d90283f | |
|
|
f203942ba2 | |
|
|
3340fc72a6 | |
|
|
527cbe513a | |
|
|
902aec6758 | |
|
|
fd0a4f5881 | |
|
|
0987f9d173 | |
|
|
2ed8170c6f | |
|
|
d779b3e0fc | |
|
|
3d995d8c97 | |
|
|
357f451338 | |
|
|
3cb28afab6 | |
|
|
1545295ad4 | |
|
|
bacbed2c07 | |
|
|
206172d9f1 | |
|
|
7f587ef7f9 | |
|
|
5433dc99b3 | |
|
|
bccf37f527 | |
|
|
794c5b35d0 | |
|
|
6b79d94608 | |
|
|
d1270a2ba3 | |
|
|
a5693087f0 | |
|
|
2db9e60640 | |
|
|
57b4382f0c | |
|
|
03b547c21e | |
|
|
250af4351d | |
|
|
f4d00290ed | |
|
|
67475f53e0 | |
|
|
febf4666fb | |
|
|
ffb13159f1 | |
|
|
d9bdbc1048 | |
|
|
f8f6f790aa | |
|
|
508b02fc8a | |
|
|
2cd009dffe | |
|
|
c1151f761f | |
|
|
5e1829d414 | |
|
|
dab6fac705 | |
|
|
3d066264ac | |
|
|
94f04a532d | |
|
|
c26743a145 | |
|
|
f69a9e0fdc | |
|
|
dec8c6a8ac | |
|
|
23589dc78b |
|
|
@ -11,9 +11,9 @@ ahci_test
|
|||
ascii.bitmaps
|
||||
ascii.h
|
||||
autom4te.cache
|
||||
build-grub-gen-asciih
|
||||
build-grub-gen-widthspec
|
||||
build-grub-mkfont
|
||||
build-VasEBoot-gen-asciih
|
||||
build-VasEBoot-gen-widthspec
|
||||
build-VasEBoot-mkfont
|
||||
cdboot_test
|
||||
cmp_test
|
||||
config.cache
|
||||
|
|
@ -31,7 +31,7 @@ docs/*.info
|
|||
docs/stamp-vti
|
||||
docs/version.texi
|
||||
ehci_test
|
||||
example_grub_script_test
|
||||
example_VasEBoot_script_test
|
||||
example_scripted_test
|
||||
example_unit_test
|
||||
*.exec
|
||||
|
|
@ -42,101 +42,102 @@ gensymlist.sh
|
|||
gentrigtables
|
||||
gentrigtables.exe
|
||||
gettext_strings_test
|
||||
grub-bin2h
|
||||
/grub-bios-setup
|
||||
/grub-bios-setup.exe
|
||||
grub_cmd_date
|
||||
grub_cmd_echo
|
||||
grub_cmd_regexp
|
||||
grub_cmd_set_date
|
||||
grub_cmd_sleep
|
||||
/grub-editenv
|
||||
/grub-editenv.exe
|
||||
grub-emu
|
||||
grub-emu-lite
|
||||
grub-emu.exe
|
||||
grub-emu-lite.exe
|
||||
grub_emu_init.c
|
||||
grub_emu_init.h
|
||||
/grub-file
|
||||
/grub-file.exe
|
||||
grub-fstest
|
||||
grub-fstest.exe
|
||||
grub_fstest_init.c
|
||||
grub_fstest_init.h
|
||||
grub_func_test
|
||||
grub-install
|
||||
grub-install.exe
|
||||
grub-kbdcomp
|
||||
/grub-macbless
|
||||
/grub-macbless.exe
|
||||
grub-macho2img
|
||||
/grub-menulst2cfg
|
||||
/grub-menulst2cfg.exe
|
||||
/grub-mk*
|
||||
grub-mount
|
||||
/grub-ofpathname
|
||||
/grub-ofpathname.exe
|
||||
grub-core/build-grub-pe2elf.exe
|
||||
/grub-probe
|
||||
/grub-probe.exe
|
||||
grub_probe_init.c
|
||||
grub_probe_init.h
|
||||
/grub-reboot
|
||||
grub_script_blanklines
|
||||
grub_script_blockarg
|
||||
grub_script_break
|
||||
grub-script-check
|
||||
grub-script-check.exe
|
||||
grub_script_check_init.c
|
||||
grub_script_check_init.h
|
||||
grub_script_comments
|
||||
grub_script_continue
|
||||
grub_script_dollar
|
||||
grub_script_echo1
|
||||
grub_script_echo_keywords
|
||||
grub_script_escape_comma
|
||||
grub_script_eval
|
||||
grub_script_expansion
|
||||
grub_script_final_semicolon
|
||||
grub_script_for1
|
||||
grub_script_functions
|
||||
grub_script_gettext
|
||||
grub_script_if
|
||||
grub_script_leading_whitespace
|
||||
grub_script_no_commands
|
||||
grub_script_not
|
||||
grub_script_return
|
||||
grub_script_setparams
|
||||
grub_script_shift
|
||||
grub_script_strcmp
|
||||
grub_script_test
|
||||
grub_script_vars1
|
||||
grub_script_while1
|
||||
grub_script.tab.c
|
||||
grub_script.tab.h
|
||||
grub_script.yy.c
|
||||
grub_script.yy.h
|
||||
grub-set-default
|
||||
grub_setup_init.c
|
||||
grub_setup_init.h
|
||||
grub-shell
|
||||
grub-shell-tester
|
||||
grub-sparc64-setup
|
||||
grub-sparc64-setup.exe
|
||||
/grub-syslinux2cfg
|
||||
/grub-syslinux2cfg.exe
|
||||
gpt_unit_test
|
||||
VasEBoot-bin2h
|
||||
/VasEBoot-bios-setup
|
||||
/VasEBoot-bios-setup.exe
|
||||
VasEBoot_cmd_date
|
||||
VasEBoot_cmd_echo
|
||||
VasEBoot_cmd_regexp
|
||||
VasEBoot_cmd_set_date
|
||||
VasEBoot_cmd_sleep
|
||||
/VasEBoot-editenv
|
||||
/VasEBoot-editenv.exe
|
||||
VasEBoot-emu
|
||||
VasEBoot-emu-lite
|
||||
VasEBoot-emu.exe
|
||||
VasEBoot-emu-lite.exe
|
||||
VasEBoot_emu_init.c
|
||||
VasEBoot_emu_init.h
|
||||
/VasEBoot-file
|
||||
/VasEBoot-file.exe
|
||||
VasEBoot-fstest
|
||||
VasEBoot-fstest.exe
|
||||
VasEBoot_fstest_init.c
|
||||
VasEBoot_fstest_init.h
|
||||
VasEBoot_func_test
|
||||
VasEBoot-install
|
||||
VasEBoot-install.exe
|
||||
VasEBoot-kbdcomp
|
||||
/VasEBoot-macbless
|
||||
/VasEBoot-macbless.exe
|
||||
VasEBoot-macho2img
|
||||
/VasEBoot-menulst2cfg
|
||||
/VasEBoot-menulst2cfg.exe
|
||||
/VasEBoot-mk*
|
||||
VasEBoot-mount
|
||||
/VasEBoot-ofpathname
|
||||
/VasEBoot-ofpathname.exe
|
||||
VasEBoot-core/build-VasEBoot-pe2elf.exe
|
||||
/VasEBoot-probe
|
||||
/VasEBoot-probe.exe
|
||||
VasEBoot_probe_init.c
|
||||
VasEBoot_probe_init.h
|
||||
/VasEBoot-reboot
|
||||
VasEBoot_script_blanklines
|
||||
VasEBoot_script_blockarg
|
||||
VasEBoot_script_break
|
||||
VasEBoot-script-check
|
||||
VasEBoot-script-check.exe
|
||||
VasEBoot_script_check_init.c
|
||||
VasEBoot_script_check_init.h
|
||||
VasEBoot_script_comments
|
||||
VasEBoot_script_continue
|
||||
VasEBoot_script_dollar
|
||||
VasEBoot_script_echo1
|
||||
VasEBoot_script_echo_keywords
|
||||
VasEBoot_script_escape_comma
|
||||
VasEBoot_script_eval
|
||||
VasEBoot_script_expansion
|
||||
VasEBoot_script_final_semicolon
|
||||
VasEBoot_script_for1
|
||||
VasEBoot_script_functions
|
||||
VasEBoot_script_gettext
|
||||
VasEBoot_script_if
|
||||
VasEBoot_script_leading_whitespace
|
||||
VasEBoot_script_no_commands
|
||||
VasEBoot_script_not
|
||||
VasEBoot_script_return
|
||||
VasEBoot_script_setparams
|
||||
VasEBoot_script_shift
|
||||
VasEBoot_script_strcmp
|
||||
VasEBoot_script_test
|
||||
VasEBoot_script_vars1
|
||||
VasEBoot_script_while1
|
||||
VasEBoot_script.tab.c
|
||||
VasEBoot_script.tab.h
|
||||
VasEBoot_script.yy.c
|
||||
VasEBoot_script.yy.h
|
||||
VasEBoot-set-default
|
||||
VasEBoot_setup_init.c
|
||||
VasEBoot_setup_init.h
|
||||
VasEBoot-shell
|
||||
VasEBoot-shell-tester
|
||||
VasEBoot-sparc64-setup
|
||||
VasEBoot-sparc64-setup.exe
|
||||
/VasEBoot-syslinux2cfg
|
||||
/VasEBoot-syslinux2cfg.exe
|
||||
gzcompress_test
|
||||
hddboot_test
|
||||
help_test
|
||||
*.img
|
||||
*.image
|
||||
*.image.exe
|
||||
include/grub/cpu
|
||||
include/grub/machine
|
||||
include/VasEBoot/cpu
|
||||
include/VasEBoot/machine
|
||||
install-sh
|
||||
lib/libgcrypt-grub
|
||||
libgrub_a_init.c
|
||||
lib/libgcrypt-VasEBoot
|
||||
libVasEBoot_a_init.c
|
||||
*.log
|
||||
*.lst
|
||||
lzocompress_test
|
||||
|
|
@ -154,7 +155,7 @@ pata_test
|
|||
*.pf2
|
||||
*.pp
|
||||
po/*.mo
|
||||
po/grub.pot
|
||||
po/VasEBoot.pot
|
||||
po/POTFILES
|
||||
po/stamp-po
|
||||
printf_test
|
||||
|
|
@ -168,7 +169,7 @@ symlist.h
|
|||
trigtables.c
|
||||
*.trs
|
||||
uhci_test
|
||||
update-grub_lib
|
||||
update-VasEBoot_lib
|
||||
unidata.c
|
||||
xzcompress_test
|
||||
Makefile.in
|
||||
|
|
@ -180,48 +181,48 @@ compile
|
|||
depcomp
|
||||
mdate-sh
|
||||
texinfo.tex
|
||||
grub-core/lib/libgcrypt-grub
|
||||
VasEBoot-core/lib/libgcrypt-VasEBoot
|
||||
.deps
|
||||
.deps-util
|
||||
.deps-core
|
||||
.dirstamp
|
||||
Makefile.util.am
|
||||
contrib
|
||||
grub-core/bootinfo.txt
|
||||
grub-core/Makefile.core.am
|
||||
grub-core/Makefile.gcry.def
|
||||
grub-core/contrib
|
||||
grub-core/gdb_grub
|
||||
grub-core/genmod.sh
|
||||
grub-core/gensyminfo.sh
|
||||
grub-core/gmodule.pl
|
||||
grub-core/grub.chrp
|
||||
grub-core/modinfo.sh
|
||||
grub-core/*.module
|
||||
grub-core/*.module.exe
|
||||
grub-core/*.pp
|
||||
grub-core/kernel.img.bin
|
||||
util/bash-completion.d/grub
|
||||
grub-core/gnulib/alloca.h
|
||||
grub-core/gnulib/arg-nonnull.h
|
||||
grub-core/gnulib/c++defs.h
|
||||
grub-core/gnulib/charset.alias
|
||||
grub-core/gnulib/configmake.h
|
||||
grub-core/gnulib/float.h
|
||||
grub-core/gnulib/getopt.h
|
||||
grub-core/gnulib/langinfo.h
|
||||
grub-core/gnulib/ref-add.sed
|
||||
grub-core/gnulib/ref-del.sed
|
||||
grub-core/gnulib/stdio.h
|
||||
grub-core/gnulib/stdlib.h
|
||||
grub-core/gnulib/string.h
|
||||
grub-core/gnulib/strings.h
|
||||
grub-core/gnulib/sys
|
||||
grub-core/gnulib/unistd.h
|
||||
grub-core/gnulib/warn-on-use.h
|
||||
grub-core/gnulib/wchar.h
|
||||
grub-core/gnulib/wctype.h
|
||||
grub-core/rs_decoder.h
|
||||
VasEBoot-core/bootinfo.txt
|
||||
VasEBoot-core/Makefile.core.am
|
||||
VasEBoot-core/Makefile.gcry.def
|
||||
VasEBoot-core/contrib
|
||||
VasEBoot-core/gdb_VasEBoot
|
||||
VasEBoot-core/genmod.sh
|
||||
VasEBoot-core/gensyminfo.sh
|
||||
VasEBoot-core/gmodule.pl
|
||||
VasEBoot-core/VasEBoot.chrp
|
||||
VasEBoot-core/modinfo.sh
|
||||
VasEBoot-core/*.module
|
||||
VasEBoot-core/*.module.exe
|
||||
VasEBoot-core/*.pp
|
||||
VasEBoot-core/kernel.img.bin
|
||||
util/bash-completion.d/VasEBoot
|
||||
VasEBoot-core/gnulib/alloca.h
|
||||
VasEBoot-core/gnulib/arg-nonnull.h
|
||||
VasEBoot-core/gnulib/c++defs.h
|
||||
VasEBoot-core/gnulib/charset.alias
|
||||
VasEBoot-core/gnulib/configmake.h
|
||||
VasEBoot-core/gnulib/float.h
|
||||
VasEBoot-core/gnulib/getopt.h
|
||||
VasEBoot-core/gnulib/langinfo.h
|
||||
VasEBoot-core/gnulib/ref-add.sed
|
||||
VasEBoot-core/gnulib/ref-del.sed
|
||||
VasEBoot-core/gnulib/stdio.h
|
||||
VasEBoot-core/gnulib/stdlib.h
|
||||
VasEBoot-core/gnulib/string.h
|
||||
VasEBoot-core/gnulib/strings.h
|
||||
VasEBoot-core/gnulib/sys
|
||||
VasEBoot-core/gnulib/unistd.h
|
||||
VasEBoot-core/gnulib/warn-on-use.h
|
||||
VasEBoot-core/gnulib/wchar.h
|
||||
VasEBoot-core/gnulib/wctype.h
|
||||
VasEBoot-core/rs_decoder.h
|
||||
widthspec.bin
|
||||
widthspec.h
|
||||
docs/stamp-1
|
||||
|
|
@ -231,19 +232,19 @@ po/*.po
|
|||
po/*.gmo
|
||||
po/LINGUAS
|
||||
po/remove-potcdate.sed
|
||||
include/grub/gcrypt/gcrypt.h
|
||||
include/grub/gcrypt/g10lib.h
|
||||
include/VasEBoot/gcrypt/gcrypt.h
|
||||
include/VasEBoot/gcrypt/g10lib.h
|
||||
po/POTFILES.in
|
||||
po/POTFILES-shell.in
|
||||
/grub-glue-efi
|
||||
/grub-render-label
|
||||
/grub-glue-efi.exe
|
||||
/grub-render-label.exe
|
||||
grub-core/gnulib/locale.h
|
||||
grub-core/gnulib/unitypes.h
|
||||
grub-core/gnulib/uniwidth.h
|
||||
/VasEBoot-glue-efi
|
||||
/VasEBoot-render-label
|
||||
/VasEBoot-glue-efi.exe
|
||||
/VasEBoot-render-label.exe
|
||||
VasEBoot-core/gnulib/locale.h
|
||||
VasEBoot-core/gnulib/unitypes.h
|
||||
VasEBoot-core/gnulib/uniwidth.h
|
||||
build-aux/test-driver
|
||||
/garbage-gen
|
||||
/garbage-gen.exe
|
||||
/grub-fs-tester
|
||||
grub-core/build-grub-module-verifier
|
||||
/VasEBoot-fs-tester
|
||||
VasEBoot-core/build-VasEBoot-module-verifier
|
||||
|
|
|
|||
2
AUTHORS
2
AUTHORS
|
|
@ -6,7 +6,7 @@ Yoshinori K. Okuji designed and implemented the initial version.
|
|||
Jeroen Dekkers added initrd support, Multiboot support, and fixed bugs
|
||||
in ext2fs.
|
||||
|
||||
Marco Gerards added ext2fs support, grub-emu, a new command-line
|
||||
Marco Gerards added ext2fs support, VasEBoot-emu, a new command-line
|
||||
engine, and fixed many bugs.
|
||||
|
||||
Omniflux added terminfo and serial support.
|
||||
|
|
|
|||
8
BUGS
8
BUGS
|
|
@ -1,7 +1,3 @@
|
|||
GRUB team is aware of following problems:
|
||||
- Currently search and assembling multidevice abstractions scans
|
||||
all the devices which can be slow.
|
||||
- Cache isn't used correctly for video which results in slowness.
|
||||
Open bugs and issues are captured in the VAS_EBOOT bug tracking system:
|
||||
|
||||
While these are bugs their solution has a potential of breaking more and more
|
||||
seriously. So it was decided for 1.99 that they aren't fixed.
|
||||
https://savannah.gnu.org/bugs/?group=VasEBoot
|
||||
|
|
|
|||
37644
ChangeLog-2015
37644
ChangeLog-2015
File diff suppressed because it is too large
Load Diff
225
INSTALL
225
INSTALL
|
|
@ -1,42 +1,31 @@
|
|||
-*- Text -*-
|
||||
|
||||
This is the GRUB. Welcome.
|
||||
This is the VAS_EBOOT. Welcome.
|
||||
|
||||
This file contains instructions for compiling and installing the GRUB.
|
||||
This file contains instructions for compiling and installing the VAS_EBOOT.
|
||||
|
||||
Where this document refers to packages names, they are named according to the
|
||||
Debian 11 package repositories. These packages can be found by searching
|
||||
https://packages.debian.org/.
|
||||
|
||||
The Requirements
|
||||
================
|
||||
|
||||
GRUB depends on some software packages installed into your system. If
|
||||
VAS_EBOOT depends on some software packages installed into your system. If
|
||||
you don't have any of them, please obtain and install them before
|
||||
configuring the GRUB.
|
||||
configuring the VAS_EBOOT.
|
||||
|
||||
* GCC 4.1.3 or later
|
||||
Note: older versions may work but support is limited
|
||||
|
||||
Experimental support for clang 3.3 or later (results in much bigger binaries)
|
||||
* GCC 5.1.0 or later
|
||||
Experimental support for clang 8.0.0 or later (results in much bigger binaries)
|
||||
for i386, x86_64, arm (including thumb), arm64, mips(el), powerpc, sparc64
|
||||
Note: clang 3.2 or later works for i386 and x86_64 targets but results in
|
||||
much bigger binaries.
|
||||
earlier versions not tested
|
||||
Note: clang 3.2 or later works for arm
|
||||
earlier versions not tested
|
||||
Note: clang on arm64 is not supported due to
|
||||
https://llvm.org/bugs/show_bug.cgi?id=26030
|
||||
Note: clang 3.3 or later works for mips(el)
|
||||
earlier versions fail to generate .reginfo and hence gprel relocations
|
||||
fail.
|
||||
Note: clang 3.2 or later works for powerpc
|
||||
earlier versions not tested
|
||||
Note: clang 3.5 or later works for sparc64
|
||||
earlier versions return "error: unable to interface with target machine"
|
||||
Note: clang has no support for ia64 and hence you can't compile GRUB
|
||||
for ia64 with clang
|
||||
* GNU Make
|
||||
* GNU Bison 2.3 or later
|
||||
* GNU gettext 0.17 or later
|
||||
* GNU gettext
|
||||
* GNU binutils 2.9.1.0.23 or later
|
||||
* Flex 2.5.35 or later
|
||||
* pkg-config
|
||||
* GNU patch
|
||||
* wget (for downloading updated translations)
|
||||
* Other standard GNU/Unix tools
|
||||
* a libc with large file support (e.g. glibc 2.1 or later)
|
||||
|
||||
|
|
@ -44,30 +33,87 @@ On GNU/Linux, you also need:
|
|||
|
||||
* libdevmapper 1.02.34 or later (recommended)
|
||||
|
||||
For optional grub-emu features, you need:
|
||||
For optional VasEBoot-emu features, you need:
|
||||
|
||||
* SDL (recommended)
|
||||
* libpciaccess (optional)
|
||||
* libusb (optional)
|
||||
|
||||
To build GRUB's graphical terminal (gfxterm), you need:
|
||||
To build VAS_EBOOT's graphical terminal (gfxterm), you need:
|
||||
|
||||
* FreeType 2 or later
|
||||
* FreeType 2.1.5 or later
|
||||
* GNU Unifont
|
||||
|
||||
If you use a development snapshot or want to hack on GRUB you may
|
||||
To build VasEBoot-mkfont the unicode fonts are required (xfonts-unifont package
|
||||
on Debian).
|
||||
|
||||
To build the optional VasEBoot-protect utility the following is needed:
|
||||
|
||||
* libtasn1 (libtasn1-6-dev on Debian)
|
||||
|
||||
If you use a development snapshot or want to hack on VAS_EBOOT you may
|
||||
need the following.
|
||||
|
||||
* Python 2.6 or later
|
||||
* Autoconf 2.60 or later
|
||||
* Automake 1.10.1 or later
|
||||
* Python 3 (NOTE: python 2.6 should still work, but it's not tested)
|
||||
* Autoconf 2.64 or later
|
||||
* Automake 1.14 or later
|
||||
* GNU Autoconf Archive (autoconf-archive on Debian)
|
||||
|
||||
Prerequisites for make-check:
|
||||
Your distro may package cross-compiling toolchains such as the following
|
||||
incomplete list on Debian: gcc-aarch64-linux-gnu, gcc-arm-linux-gnueabihf,
|
||||
gcc-mips-linux-gnu, gcc-mipsel-linux-gnu, gcc-powerpc64-linux-gnu,
|
||||
gcc-riscv64-linux-gnu, gcc-sparc64-linux-gnu, mingw-w64 and mingw-w64-tools.
|
||||
|
||||
* qemu, specifically the binary 'qemu-system-i386'
|
||||
* xorriso 1.2.9 or later, for grub-mkrescue and grub-shell
|
||||
More cross compiling toolchains can be found at the following trusted sites:
|
||||
|
||||
Configuring the GRUB
|
||||
* https://mirrors.kernel.org/pub/tools/crosstool/
|
||||
* https://toolchains.bootlin.com/
|
||||
|
||||
Prerequisites for running make-check successfully:
|
||||
|
||||
* qemu, specifically the binary "qemu-system-ARCH" where ARCH is the
|
||||
architecture VAS_EBOOT has been built for; the "qemu-system" package on Debian
|
||||
will install all needed qemu architectures
|
||||
* OVMF, for EFI platforms (packages ovmf, ovmf-ia32, qemu-efi-arm, and
|
||||
qemu-efi-aarch64)
|
||||
* OpenBIOS, for ieee1275 platforms (packages openbios-ppc and openbios-sparc)
|
||||
* xorriso 1.2.9 or later, for VasEBoot-mkrescue and VasEBoot-shell
|
||||
* wamerican, for VasEBoot-fs-tester
|
||||
* mtools, FAT tools for EFI platforms
|
||||
* xfonts-unifont, for the functional tests
|
||||
* swtpm-tools and tpm2-tools, for TPM2 key protector tests
|
||||
|
||||
* If running a Linux kernel the following modules must be loaded:
|
||||
- fuse, loop
|
||||
- btrfs, erofs, ext4, f2fs, fat, hfs, hfsplus, jfs, mac-roman, minix, nilfs2,
|
||||
reiserfs, udf, xfs
|
||||
- On newer kernels, the exfat kernel modules may be used instead of the
|
||||
exfat FUSE filesystem
|
||||
- Kernel version 6.12.x was the last series to include reiserfs support,
|
||||
so later kernels will fail the reiser filesystem test.
|
||||
* The following are Debian named packages required mostly for the full
|
||||
suite of filesystem testing (but some are needed by other tests as well):
|
||||
- btrfs-progs, dosfstools, e2fsprogs, erofs-utils, exfatprogs, exfat-fuse,
|
||||
f2fs-tools, genromfs, hfsprogs, jfsutils, nilfs-tools, ntfs-3g,
|
||||
reiserfsprogs, squashfs-tools, reiserfsprogs, udftools, xfsprogs, zfs-fuse
|
||||
- exfat-fuse, if not using the exfat kernel module
|
||||
- gzip, lzop, xz-utils
|
||||
- attr, cpio, g++, gawk, parted, recode, tar, util-linux
|
||||
|
||||
Note that `make check' will run and many tests may complete successfully
|
||||
with only a subset of these prerequisites. However, some tests may fail
|
||||
due to missing prerequisites.
|
||||
|
||||
To build the documentation you'll need:
|
||||
* texinfo, for the info and html documentation
|
||||
* texlive, for building the dvi and pdf documentation (optional)
|
||||
|
||||
To use the gdb_VasEBoot GDB script you'll need:
|
||||
* readelf (binutils package)
|
||||
* objdump (binutils package)
|
||||
* GNU Debugger > 7, built with python support (gdb package)
|
||||
* Python >= 3.5 (python3 package)
|
||||
|
||||
Configuring the VAS_EBOOT
|
||||
====================
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
|
|
@ -91,22 +137,19 @@ called `autoconf'. You only need `configure.in' if you want to change
|
|||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
|
||||
Building the GRUB
|
||||
Building the VAS_EBOOT
|
||||
=================
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code.
|
||||
|
||||
2. Skip this and following step if you use release tarball and proceed to
|
||||
step 4. If you want translations type `./linguas.sh'.
|
||||
|
||||
3. Type `./autogen.sh'.
|
||||
2. Type `./bootstrap'.
|
||||
|
||||
* autogen.sh uses python. By default invocation is "python" but can be
|
||||
overriden by setting variable $PYTHON.
|
||||
The autogen.sh (called by bootstrap) uses python. By default it is
|
||||
autodetected, but it can be overridden by setting the PYTHON variable.
|
||||
|
||||
4. Type `./configure' to configure the package for your system.
|
||||
3. Type `./configure' to configure the package for your system.
|
||||
If you're using `csh' on an old version of System V, you might
|
||||
need to type `sh ./configure' instead to prevent `csh' from trying
|
||||
to execute `configure' itself.
|
||||
|
|
@ -114,15 +157,19 @@ The simplest way to compile this package is:
|
|||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
6. Type `make' to compile the package.
|
||||
4. Type `make' to compile the package.
|
||||
|
||||
7. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
5. Optionally, type `make check' to run any self-tests that come with
|
||||
the package. Note that many of the tests require root privileges and
|
||||
a specially crafted environment in order to run.
|
||||
|
||||
8. Type `make install' to install the programs and any data files and
|
||||
6. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
9. You can remove the program binaries and object files from the
|
||||
7. Type `make html' or `make pdf' to generate the html or pdf
|
||||
documentation. Note, these are not built by default.
|
||||
|
||||
8. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
|
|
@ -131,16 +178,16 @@ The simplest way to compile this package is:
|
|||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Cross-compiling the GRUB
|
||||
Cross-compiling the VAS_EBOOT
|
||||
========================
|
||||
|
||||
GRUB defines 3 platforms:
|
||||
VAS_EBOOT defines 3 platforms:
|
||||
|
||||
- "Build" is the one which build systems runs on.
|
||||
- "Host" is where you execute GRUB utils.
|
||||
- "Target" is where GRUB itself runs.
|
||||
- "Host" is where you execute VAS_EBOOT utils.
|
||||
- "Target" is where VAS_EBOOT itself runs.
|
||||
|
||||
For grub-emu host and target must be the same but may differ from build.
|
||||
For VasEBoot-emu host and target must be the same but may differ from build.
|
||||
|
||||
If build and host are different make check isn't available.
|
||||
|
||||
|
|
@ -158,42 +205,59 @@ For this example the configure line might look like (more details below)
|
|||
(some options are optional and included here for completeness but some rarely
|
||||
used options are omitted):
|
||||
|
||||
./configure BUILD_CC=gcc BUILD_FREETYPE=freetype-config --host=amd64-linux-gnu
|
||||
CC=amd64-linux-gnu-gcc CFLAGS="-g -O2" FREETYPE=amd64-linux-gnu-freetype-config
|
||||
--target=arm --with-platform=uboot TARGET_CC=arm-elf-gcc
|
||||
TARGET_CFLAGS="-Os -march=armv6" TARGET_CCASFLAGS="-march=armv6"
|
||||
TARGET_OBJCOPY="arm-elf-objcopy" TARGET_STRIP="arm-elf-strip"
|
||||
TARGET_NM=arm-elf-nm TARGET_RANLIB=arm-elf-ranlib LEX=gflex
|
||||
./configure --build=sparc64-freebsd --host=x86_64-linux-gnu \
|
||||
--target=arm-linux-gnueabihf --with-platform=efi \
|
||||
BUILD_CC=gcc BUILD_PKG_CONFIG=pkg-config \
|
||||
HOST_CC=x86_64-linux-gnu-gcc HOST_CFLAGS='-g -O2' \
|
||||
PKG_CONFIG=x86_64-linux-gnu-pkg-config TARGET_CC=arm-linux-gnueabihf-gcc \
|
||||
TARGET_CFLAGS='-Os -march=armv8.3-a' TARGET_CCASFLAGS='-march=armv8.3-a' \
|
||||
TARGET_OBJCOPY=arm-linux-gnueabihf-objcopy \
|
||||
TARGET_STRIP=arm-linux-gnueabihf-strip TARGET_NM=arm-linux-gnueabihf-nm \
|
||||
TARGET_RANLIB=arm-linux-gnueabihf-ranlib LEX=flex
|
||||
|
||||
Note, that the autoconf 2.65 manual states that when using the --host argument
|
||||
to configure, the --build argument should be specified as well. Not sending
|
||||
--build, enters a compatibility mode that will be removed in the future.
|
||||
|
||||
Normally, for building a VAS_EBOOT on amd64 with tools to run on amd64 to
|
||||
generate images to run on ARM, using your Linux distribution's
|
||||
packaged cross compiler, the following would suffice:
|
||||
|
||||
./configure --target=arm-linux-gnueabihf --with-platform=efi
|
||||
|
||||
You need to use following options to specify tools and platforms. For minimum
|
||||
version look at prerequisites. All tools not mentioned in this section under
|
||||
corresponding platform are not needed for the platform in question.
|
||||
|
||||
- For build
|
||||
1. BUILD_CC= to gcc able to compile for build. This is used, for
|
||||
1. --build= to autoconf name of build.
|
||||
2. BUILD_CC= to gcc able to compile for build. This is used, for
|
||||
example, to compile build-gentrigtables which is then run to
|
||||
generate sin and cos tables.
|
||||
2. BUILD_CFLAGS= for C options for build.
|
||||
3. BUILD_CPPFLAGS= for C preprocessor options for build.
|
||||
4. BUILD_LDFLAGS= for linker options for build.
|
||||
5. BUILD_FREETYPE= for freetype-config for build (optional).
|
||||
3. BUILD_CFLAGS= for C options for build.
|
||||
4. BUILD_CPPFLAGS= for C preprocessor options for build.
|
||||
5. BUILD_LDFLAGS= for linker options for build.
|
||||
6. BUILD_PKG_CONFIG= for pkg-config for build (optional).
|
||||
|
||||
- For host
|
||||
1. --host= to autoconf name of host.
|
||||
2. CC= for gcc able to compile for host
|
||||
3. HOST_CFLAGS= for C options for host.
|
||||
4. HOST_CPPFLAGS= for C preprocessor options for host.
|
||||
5. HOST_LDFLAGS= for linker options for host.
|
||||
6. FREETYPE= for freetype-config for host (optional).
|
||||
7. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional).
|
||||
8. Libfuse if any must be in standard linker folders (-lfuse) (optional).
|
||||
9. Libzfs if any must be in standard linker folders (-lzfs) (optional).
|
||||
10. Liblzma if any must be in standard linker folders (-llzma) (optional).
|
||||
2. CC= for gcc able to compile for host.
|
||||
3. CFLAGS= for C options for host.
|
||||
4. HOST_CC= for gcc able to compile for host.
|
||||
5. HOST_CFLAGS= for C options for host.
|
||||
6. HOST_CPPFLAGS= for C preprocessor options for host.
|
||||
7. HOST_LDFLAGS= for linker options for host.
|
||||
8. PKG_CONFIG= for pkg-config for host (optional).
|
||||
9. Libdevmapper if any must be in standard linker folders (-ldevmapper) (optional).
|
||||
10. Libfuse if any must be in standard linker folders (-lfuse) (optional).
|
||||
11. Libzfs if any must be in standard linker folders (-lzfs) (optional).
|
||||
12. Liblzma if any must be in standard linker folders (-llzma) (optional).
|
||||
Note: The HOST_* variables override not prefixed variables.
|
||||
|
||||
- For target
|
||||
1. --target= to autoconf cpu name of target.
|
||||
2. --with-platform to choose firmware.
|
||||
3. TARGET_CC= for gcc able to compile for target
|
||||
3. TARGET_CC= for gcc able to compile for target.
|
||||
4. TARGET_CFLAGS= for C options for target.
|
||||
5. TARGET_CPPFLAGS= for C preprocessor options for target.
|
||||
6. TARGET_CCASFLAGS= for assembler options for target.
|
||||
|
|
@ -202,11 +266,14 @@ corresponding platform are not needed for the platform in question.
|
|||
9. TARGET_STRIP= for strip for target.
|
||||
10. TARGET_NM= for nm for target.
|
||||
11. TARGET_RANLIB= for ranlib for target.
|
||||
Note: If the TARGET_* variables are not specified then they will default
|
||||
to be the same as the host variables. If host variables are not
|
||||
specified then the TARGET_* variables will default to be the same
|
||||
as not prefixed variables.
|
||||
|
||||
- Additionally for emu, for host and target.
|
||||
1. SDL is looked for in standard linker directories (-lSDL) (optional)
|
||||
2. libpciaccess is looked for in standard linker directories (-lpciaccess) (optional)
|
||||
3. libusb is looked for in standard linker directories (-lusb) (optional)
|
||||
|
||||
- Platform-agnostic tools and data.
|
||||
1. make is the tool you execute after ./configure.
|
||||
|
|
@ -247,10 +314,10 @@ If the package supports it, you can cause programs to be installed
|
|||
with an extra prefix or suffix on their names by giving `configure'
|
||||
the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Please note, however, that the GRUB knows where it is located in the
|
||||
Please note, however, that the VAS_EBOOT knows where it is located in the
|
||||
filesystem. If you have installed it in an unusual location, the
|
||||
system might not work properly, or at all. The chief utility of these
|
||||
options for the GRUB is to allow you to "install" in some alternate
|
||||
options for the VAS_EBOOT is to allow you to "install" in some alternate
|
||||
location, and then copy these to the actual root filesystem later.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
List of current VAS_EBOOT maintainers and some basic information about the project
|
||||
=============================================================================
|
||||
|
||||
Here is the list of current VAS_EBOOT maintainers:
|
||||
- Daniel Kiper <daniel.kiper@oracle.com> and <dkiper@net-space.pl>,
|
||||
- Alex Burmashev <alexander.burmashev@oracle.com>,
|
||||
- Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>.
|
||||
|
||||
The maintainers drive and overlook the VAS_EBOOT development.
|
||||
|
||||
If you found a security vulnerability in the VAS_EBOOT please check the SECURITY
|
||||
file to get more information how to properly report this kind of bugs to
|
||||
the maintainers.
|
||||
|
||||
The VAS_EBOOT development happens on the VasEBoot-devel mailing list [1]. The latest
|
||||
VAS_EBOOT source code is available at Savannah git repository [2].
|
||||
|
||||
Users can ask for help on the help-VasEBoot mailing list [3].
|
||||
|
||||
|
||||
List of past VAS_EBOOT maintainers and people who strongly contributed to the project
|
||||
================================================================================
|
||||
|
||||
Here is the list, sorted alphabetically, of past VAS_EBOOT maintainers and people who
|
||||
strongly contributed to the project:
|
||||
- Andrei Borzenkov,
|
||||
- Bryan Ford,
|
||||
- Erich Stefan Boleyn,
|
||||
- Gordon Matzigkeit,
|
||||
- Yoshinori K. Okuji.
|
||||
|
||||
|
||||
[1] https://lists.gnu.org/mailman/listinfo/VasEBoot-devel
|
||||
[2] https://git.savannah.gnu.org/gitweb/?p=VasEBoot.git&view=view+git+repository
|
||||
[3] https://lists.gnu.org/mailman/listinfo/help-VasEBoot
|
||||
289
Makefile.am
289
Makefile.am
|
|
@ -1,9 +1,9 @@
|
|||
AUTOMAKE_OPTIONS = subdir-objects -Wno-portability
|
||||
|
||||
DEPDIR = .deps-util
|
||||
SUBDIRS = grub-core/gnulib .
|
||||
SUBDIRS = VasEBoot-core/lib/gnulib .
|
||||
if COND_real_platform
|
||||
SUBDIRS += grub-core
|
||||
SUBDIRS += VasEBoot-core
|
||||
endif
|
||||
SUBDIRS += po docs util/bash-completion.d
|
||||
|
||||
|
|
@ -24,45 +24,54 @@ CCASFLAGS_PROGRAM += $(CCASFLAGS_GNULIB)
|
|||
|
||||
include $(srcdir)/Makefile.util.am
|
||||
|
||||
check_SCRIPTS = $(check_SCRIPTS_native) $(check_SCRIPTS_nonnative)
|
||||
check_PROGRAMS = $(check_PROGRAMS_native) $(check_PROGRAMS_nonnative)
|
||||
TESTS = $(check_SCRIPTS) $(check_PROGRAMS)
|
||||
|
||||
check-native:
|
||||
$(MAKE) TESTS="$(check_PROGRAMS_native) $(check_SCRIPTS_native)" check
|
||||
check-nonnative:
|
||||
$(MAKE) TESTS="$(check_PROGRAMS_nonnative) $(check_SCRIPTS_nonnative)" check
|
||||
|
||||
# XXX Use Automake's LEX & YACC support
|
||||
grub_script.tab.h: $(top_srcdir)/grub-core/script/parser.y
|
||||
$(YACC) -d -p grub_script_yy -b grub_script $(top_srcdir)/grub-core/script/parser.y
|
||||
grub_script.tab.c: grub_script.tab.h
|
||||
CLEANFILES += grub_script.tab.c grub_script.tab.h
|
||||
VasEBoot_script.tab.h: $(top_srcdir)/VasEBoot-core/script/parser.y
|
||||
$(YACC) -d -p VasEBoot_script_yy -b VasEBoot_script $(top_srcdir)/VasEBoot-core/script/parser.y
|
||||
VasEBoot_script.tab.c: VasEBoot_script.tab.h
|
||||
CLEANFILES += VasEBoot_script.tab.c VasEBoot_script.tab.h
|
||||
|
||||
# For the lexer.
|
||||
grub_script.yy.h: $(top_srcdir)/grub-core/script/yylex.l
|
||||
$(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $(top_srcdir)/grub-core/script/yylex.l
|
||||
grub_script.yy.c: grub_script.yy.h
|
||||
CLEANFILES += grub_script.yy.c grub_script.yy.h
|
||||
VasEBoot_script.yy.h: $(top_srcdir)/VasEBoot-core/script/yylex.l
|
||||
$(LEX) -o VasEBoot_script.yy.c --header-file=VasEBoot_script.yy.h $(top_srcdir)/VasEBoot-core/script/yylex.l
|
||||
VasEBoot_script.yy.c: VasEBoot_script.yy.h
|
||||
CLEANFILES += VasEBoot_script.yy.c VasEBoot_script.yy.h
|
||||
|
||||
# For libgrub.a
|
||||
libgrub.pp: grub_script.tab.h grub_script.yy.h $(libgrubmods_a_SOURCES) $(libgrubkern_a_SOURCES)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgrubmods_a_CPPFLAGS) $(libgrubkern_a_CPPFLAGS) $(CPPFLAGS) \
|
||||
-D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += libgrub.pp
|
||||
# For libVasEBoot.a
|
||||
libVasEBoot.pp: config-util.h VasEBoot_script.tab.h VasEBoot_script.yy.h $(libVasEBootmods_a_SOURCES) $(libVasEBootkern_a_SOURCES)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libVasEBootmods_a_CPPFLAGS) $(libVasEBootkern_a_CPPFLAGS) $(CPPFLAGS) \
|
||||
-D'VAS_EBOOT_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += libVasEBoot.pp
|
||||
|
||||
libgrub_a_init.lst: libgrub.pp
|
||||
cat $< | grep '@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += libgrub_a_init.lst
|
||||
libVasEBoot_a_init.lst: libVasEBoot.pp
|
||||
cat $< | grep '^@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += libVasEBoot_a_init.lst
|
||||
|
||||
libgrub_a_init.c: libgrub_a_init.lst $(top_srcdir)/geninit.sh
|
||||
libVasEBoot_a_init.c: libVasEBoot_a_init.lst $(top_srcdir)/geninit.sh
|
||||
sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += libgrub_a_init.c
|
||||
CLEANFILES += libVasEBoot_a_init.c
|
||||
|
||||
# For grub-fstest
|
||||
grub_fstest.pp: $(grub_fstest_SOURCES)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(grub_fstest_CPPFLAGS) $(CPPFLAGS) \
|
||||
-D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += grub_fstest.pp
|
||||
# For VasEBoot-fstest
|
||||
VasEBoot_fstest.pp: config-util.h $(VasEBoot_fstest_SOURCES)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(VasEBoot_fstest_CPPFLAGS) $(CPPFLAGS) \
|
||||
-D'VAS_EBOOT_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += VasEBoot_fstest.pp
|
||||
|
||||
grub_fstest_init.lst: libgrub.pp grub_fstest.pp
|
||||
cat $^ | grep '@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += grub_fstest_init.lst
|
||||
VasEBoot_fstest_init.lst: libVasEBoot.pp VasEBoot_fstest.pp
|
||||
cat $^ | grep '^@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += VasEBoot_fstest_init.lst
|
||||
|
||||
grub_fstest_init.c: grub_fstest_init.lst $(top_srcdir)/geninit.sh
|
||||
VasEBoot_fstest_init.c: VasEBoot_fstest_init.lst $(top_srcdir)/geninit.sh
|
||||
sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += grub_fstest_init.c
|
||||
CLEANFILES += VasEBoot_fstest_init.c
|
||||
|
||||
if COND_HAVE_FONT_SOURCE
|
||||
pkgdata_DATA += unicode.pf2 ascii.pf2 euro.pf2 ascii.h widthspec.h
|
||||
|
|
@ -70,39 +79,39 @@ endif
|
|||
|
||||
starfield_theme_files = $(srcdir)/themes/starfield/blob_w.png $(srcdir)/themes/starfield/boot_menu_c.png $(srcdir)/themes/starfield/boot_menu_e.png $(srcdir)/themes/starfield/boot_menu_ne.png $(srcdir)/themes/starfield/boot_menu_n.png $(srcdir)/themes/starfield/boot_menu_nw.png $(srcdir)/themes/starfield/boot_menu_se.png $(srcdir)/themes/starfield/boot_menu_s.png $(srcdir)/themes/starfield/boot_menu_sw.png $(srcdir)/themes/starfield/boot_menu_w.png $(srcdir)/themes/starfield/slider_c.png $(srcdir)/themes/starfield/slider_n.png $(srcdir)/themes/starfield/slider_s.png $(srcdir)/themes/starfield/starfield.png $(srcdir)/themes/starfield/terminal_box_c.png $(srcdir)/themes/starfield/terminal_box_e.png $(srcdir)/themes/starfield/terminal_box_ne.png $(srcdir)/themes/starfield/terminal_box_n.png $(srcdir)/themes/starfield/terminal_box_nw.png $(srcdir)/themes/starfield/terminal_box_se.png $(srcdir)/themes/starfield/terminal_box_s.png $(srcdir)/themes/starfield/terminal_box_sw.png $(srcdir)/themes/starfield/terminal_box_w.png $(srcdir)/themes/starfield/theme.txt $(srcdir)/themes/starfield/README $(srcdir)/themes/starfield/COPYING.CC-BY-SA-3.0
|
||||
|
||||
build-grub-mkfont$(BUILD_EXEEXT): util/grub-mkfont.c grub-core/unidata.c grub-core/kern/emu/misc.c util/misc.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-mkfont\" $^ $(build_freetype_cflags) $(build_freetype_libs)
|
||||
CLEANFILES += build-grub-mkfont$(BUILD_EXEEXT)
|
||||
build-VasEBoot-mkfont$(BUILD_EXEEXT): util/VasEBoot-mkfont.c VasEBoot-core/unidata.c VasEBoot-core/kern/emu/misc.c util/misc.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DVAS_EBOOT_MKFONT=1 -DVAS_EBOOT_BUILD=1 -DVAS_EBOOT_UTIL=1 -DVAS_EBOOT_BUILD_PROGRAM_NAME=\"build-VasEBoot-mkfont\" $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS)
|
||||
CLEANFILES += build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
|
||||
garbage-gen$(BUILD_EXEEXT): util/garbage-gen.c
|
||||
$(BUILD_CC) -o $@ $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $^
|
||||
CLEANFILES += garbage-gen$(BUILD_EXEEXT)
|
||||
EXTRA_DIST += util/garbage-gen.c
|
||||
|
||||
build-grub-gen-asciih$(BUILD_EXEEXT): util/grub-gen-asciih.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) -Wall -Werror
|
||||
CLEANFILES += build-grub-gen-asciih$(BUILD_EXEEXT)
|
||||
build-VasEBoot-gen-asciih$(BUILD_EXEEXT): util/VasEBoot-gen-asciih.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DVAS_EBOOT_MKFONT=1 -DVAS_EBOOT_BUILD=1 -DVAS_EBOOT_UTIL=1 $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -Wall -Werror
|
||||
CLEANFILES += build-VasEBoot-gen-asciih$(BUILD_EXEEXT)
|
||||
|
||||
build-grub-gen-widthspec$(BUILD_EXEEXT): util/grub-gen-widthspec.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_MKFONT=1 -DGRUB_BUILD=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) -Wall -Werror
|
||||
CLEANFILES += build-grub-gen-widthspec$(BUILD_EXEEXT)
|
||||
build-VasEBoot-gen-widthspec$(BUILD_EXEEXT): util/VasEBoot-gen-widthspec.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DVAS_EBOOT_MKFONT=1 -DVAS_EBOOT_BUILD=1 -DVAS_EBOOT_UTIL=1 $^ $(BUILD_FREETYPE_CFLAGS) $(BUILD_FREETYPE_LIBS) -Wall -Werror
|
||||
CLEANFILES += build-VasEBoot-gen-widthspec$(BUILD_EXEEXT)
|
||||
|
||||
if COND_STARFIELD
|
||||
starfield_DATA = dejavu_10.pf2 dejavu_12.pf2 dejavu_bold_14.pf2 dejavu_14.pf2 dejavu_16.pf2 $(starfield_theme_files)
|
||||
dejavu_10.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
|
||||
./build-grub-mkfont$(BUILD_EXEEXT) -s 10 -o $@ $(DJVU_FONT_SOURCE)
|
||||
dejavu_10.pf2: $(DJVU_FONT_SOURCE) build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-mkfont$(BUILD_EXEEXT) -s 10 -o $@ $(DJVU_FONT_SOURCE)
|
||||
CLEANFILES += dejavu_10.pf2
|
||||
dejavu_12.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
|
||||
./build-grub-mkfont$(BUILD_EXEEXT) -s 12 -o $@ $(DJVU_FONT_SOURCE)
|
||||
dejavu_12.pf2: $(DJVU_FONT_SOURCE) build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-mkfont$(BUILD_EXEEXT) -s 12 -o $@ $(DJVU_FONT_SOURCE)
|
||||
CLEANFILES += dejavu_12.pf2
|
||||
dejavu_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
|
||||
./build-grub-mkfont$(BUILD_EXEEXT) -s 14 -o $@ $(DJVU_FONT_SOURCE)
|
||||
dejavu_14.pf2: $(DJVU_FONT_SOURCE) build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-mkfont$(BUILD_EXEEXT) -s 14 -o $@ $(DJVU_FONT_SOURCE)
|
||||
CLEANFILES += dejavu_14.pf2
|
||||
dejavu_bold_14.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
|
||||
./build-grub-mkfont$(BUILD_EXEEXT) -b -s 14 -o $@ $(DJVU_FONT_SOURCE)
|
||||
dejavu_bold_14.pf2: $(DJVU_FONT_SOURCE) build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-mkfont$(BUILD_EXEEXT) -b -s 14 -o $@ $(DJVU_FONT_SOURCE)
|
||||
CLEANFILES += dejavu_bold_14.pf2
|
||||
dejavu_16.pf2: $(DJVU_FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
|
||||
./build-grub-mkfont$(BUILD_EXEEXT) -s 16 -o $@ $(DJVU_FONT_SOURCE)
|
||||
dejavu_16.pf2: $(DJVU_FONT_SOURCE) build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-mkfont$(BUILD_EXEEXT) -s 16 -o $@ $(DJVU_FONT_SOURCE)
|
||||
CLEANFILES += dejavu_16.pf2
|
||||
else
|
||||
starfield_DATA =
|
||||
|
|
@ -111,34 +120,34 @@ endif
|
|||
EXTRA_DIST += $(starfield_theme_files)
|
||||
EXTRA_DIST += $(srcdir)/themes/starfield/src/slider_s.xcf $(srcdir)/themes/starfield/src/slider_n.xcf $(srcdir)/themes/starfield/src/slider_c.xcf $(srcdir)/themes/starfield/src/blob_nw.xcf $(srcdir)/themes/starfield/src/bootmenu/center.xcf $(srcdir)/themes/starfield/src/bootmenu/corner.xcf $(srcdir)/themes/starfield/src/bootmenu/side.xcf $(srcdir)/themes/starfield/src/terminalbox/side.xcf $(srcdir)/themes/starfield/src/terminalbox/corner.xcf $(srcdir)/themes/starfield/src/terminalbox/center.xcf
|
||||
|
||||
unicode.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
|
||||
./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1)
|
||||
unicode.pf2: $(FONT_SOURCE) build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) || (rm -f $@; exit 1)
|
||||
CLEANFILES += unicode.pf2
|
||||
|
||||
# Arrows and lines are needed to draw the menu, so always include them
|
||||
UNICODE_ARROWS=0x2190-0x2193
|
||||
UNICODE_LINES=0x2501-0x251B
|
||||
|
||||
ascii.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
|
||||
./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
|
||||
ascii.pf2: $(FONT_SOURCE) build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
|
||||
CLEANFILES += ascii.pf2
|
||||
|
||||
euro.pf2: $(FONT_SOURCE) build-grub-mkfont$(BUILD_EXEEXT)
|
||||
./build-grub-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
|
||||
euro.pf2: $(FONT_SOURCE) build-VasEBoot-mkfont$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-mkfont$(BUILD_EXEEXT) -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) || (rm -f $@; exit 1)
|
||||
CLEANFILES += euro.pf2
|
||||
|
||||
ascii.h: $(FONT_SOURCE) build-grub-gen-asciih$(BUILD_EXEEXT)
|
||||
./build-grub-gen-asciih$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
|
||||
ascii.h: $(FONT_SOURCE) build-VasEBoot-gen-asciih$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-gen-asciih$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += ascii.h
|
||||
|
||||
widthspec.h: $(FONT_SOURCE) build-grub-gen-widthspec$(BUILD_EXEEXT)
|
||||
./build-grub-gen-widthspec$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
|
||||
widthspec.h: $(FONT_SOURCE) build-VasEBoot-gen-widthspec$(BUILD_EXEEXT)
|
||||
./build-VasEBoot-gen-widthspec$(BUILD_EXEEXT) $(FONT_SOURCE) $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += widthspec.h
|
||||
|
||||
# Install config.h into platformdir
|
||||
nodist_platform_HEADERS = config.h
|
||||
|
||||
pkgdata_DATA += grub-mkconfig_lib
|
||||
pkgdata_DATA += VasEBoot-mkconfig_lib
|
||||
|
||||
|
||||
if COND_real_platform
|
||||
|
|
@ -178,64 +187,64 @@ QEMU32=qemu-system-x86_64
|
|||
MINIMUM_CPU_LINUX=core2duo
|
||||
endif
|
||||
|
||||
linux.init.x86_64: $(srcdir)/grub-core/tests/boot/linux.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
linux.init.x86_64: $(srcdir)/VasEBoot-core/tests/boot/linux.init-x86_64.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -static -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.i386: $(srcdir)/grub-core/tests/boot/linux.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
linux.init.i386: $(srcdir)/VasEBoot-core/tests/boot/linux.init-i386.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -static -m32 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.mips: $(srcdir)/grub-core/tests/boot/linux.init-mips.S
|
||||
linux.init.mips: $(srcdir)/VasEBoot-core/tests/boot/linux.init-mips.S
|
||||
$(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.ppc: $(srcdir)/grub-core/tests/boot/linux.init-ppc.S
|
||||
linux.init.ppc: $(srcdir)/VasEBoot-core/tests/boot/linux.init-ppc.S
|
||||
$(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.mipsel: $(srcdir)/grub-core/tests/boot/linux.init-mips.S
|
||||
linux.init.mipsel: $(srcdir)/VasEBoot-core/tests/boot/linux.init-mips.S
|
||||
$(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux.init.loongson: $(srcdir)/grub-core/tests/boot/linux.init-mips.S
|
||||
linux.init.loongson: $(srcdir)/VasEBoot-core/tests/boot/linux.init-mips.S
|
||||
$(TARGET_CC) -o $@ $< -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -DREBOOT=1
|
||||
|
||||
multiboot.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
multiboot.elf: $(srcdir)/VasEBoot-core/tests/boot/kernel-i386.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -DTARGET_MULTIBOOT=1 -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include
|
||||
|
||||
kfreebsd.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
kfreebsd.elf: $(srcdir)/VasEBoot-core/tests/boot/kernel-i386.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include
|
||||
|
||||
kfreebsd.aout: kfreebsd.elf
|
||||
$(TARGET_OBJCOPY) -O a.out-i386-linux $< $@ -j .text
|
||||
|
||||
pc-chainloader.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
pc-chainloader.elf: $(srcdir)/VasEBoot-core/tests/boot/kernel-8086.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -static -DTARGET_CHAINLOADER=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x7c00 -m32
|
||||
|
||||
pc-chainloader.bin: pc-chainloader.elf
|
||||
$(TARGET_OBJCOPY) -O binary --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .reginfo -R .rel.dyn -R .note.gnu.gold-version $< $@;
|
||||
|
||||
ntldr.elf: $(srcdir)/grub-core/tests/boot/kernel-8086.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
ntldr.elf: $(srcdir)/VasEBoot-core/tests/boot/kernel-8086.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -DTARGET_NTLDR=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -static -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0 -m32
|
||||
|
||||
ntldr.bin: ntldr.elf
|
||||
$(TARGET_OBJCOPY) -O binary --strip-unneeded -j .text $< $@;
|
||||
|
||||
multiboot2.elf: $(srcdir)/grub-core/tests/boot/kernel-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
multiboot2.elf: $(srcdir)/VasEBoot-core/tests/boot/kernel-i386.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -static -o $@ $< -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" -ffreestanding -nostdlib -nostdinc -Wl,--build-id=none -Wl,-N -Wl,-Ttext,0x100000 -m32 -I$(srcdir)/include -DTARGET_MULTIBOOT2=1
|
||||
|
||||
kfreebsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kfreebsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
kfreebsd.init.x86_64: $(srcdir)/VasEBoot-core/tests/boot/kfreebsd.init-x86_64.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m64 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@
|
||||
|
||||
kfreebsd.init.i386: $(srcdir)/grub-core/tests/boot/kfreebsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
kfreebsd.init.i386: $(srcdir)/VasEBoot-core/tests/boot/kfreebsd.init-i386.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" && freebsd-brandelf -t FreeBSD $@
|
||||
|
||||
knetbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
knetbsd.init.i386: $(srcdir)/VasEBoot-core/tests/boot/kbsd.init-i386.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DTARGET_NETBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
kopenbsd.init.i386: $(srcdir)/grub-core/tests/boot/kbsd.init-i386.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
kopenbsd.init.i386: $(srcdir)/VasEBoot-core/tests/boot/kbsd.init-i386.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m32 -static -nostdlib -nostdinc -DTARGET_OPENBSD=1 -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
knetbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
knetbsd.init.x86_64: $(srcdir)/VasEBoot-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m64 -DTARGET_NETBSD=1 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
kopenbsd.init.x86_64: $(srcdir)/grub-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
kopenbsd.init.x86_64: $(srcdir)/VasEBoot-core/tests/boot/kbsd.init-x86_64.S $(srcdir)/VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
$(TARGET_CC) -o $@ $< -m64 -DTARGET_OPENBSD=1 -static -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\"
|
||||
|
||||
linux-initramfs.mips: linux.init.mips Makefile
|
||||
|
|
@ -259,97 +268,97 @@ linux-initramfs.x86_64: linux.init.x86_64 Makefile
|
|||
kfreebsd-mfsroot.i386.img: kfreebsd.init.i386 Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||
|
||||
knetbsd.image.i386: knetbsd.init.i386 $(srcdir)/grub-core/tests/boot/kbsd.spec.txt
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||
knetbsd.image.i386: knetbsd.init.i386 $(srcdir)/VasEBoot-core/tests/boot/kbsd.spec.txt
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/VasEBoot-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||
|
||||
kopenbsd.image.i386: kopenbsd.init.i386 $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@
|
||||
kopenbsd.image.i386: kopenbsd.init.i386 $(srcdir)/VasEBoot-core/tests/boot/kopenbsdlabel.txt
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/VasEBoot-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/VasEBoot-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@
|
||||
|
||||
kopenbsd.image.x86_64: kopenbsd.init.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/grub-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@
|
||||
kopenbsd.image.x86_64: kopenbsd.init.x86_64 $(srcdir)/VasEBoot-core/tests/boot/kopenbsdlabel.txt
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/VasEBoot-core/tests/boot/kbsd.spec.txt -t ffs -s 128k -f 10 -o minfree=0,version=1 $@ $$TDIR && bsdlabel -f -R $@ $(srcdir)/VasEBoot-core/tests/boot/kopenbsdlabel.txt && rm -rf $$TDIR || rm -f $@
|
||||
|
||||
knetbsd.miniroot-image.i386.img: knetbsd.image.i386 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386
|
||||
$(TARGET_OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.i386 $@
|
||||
knetbsd.miniroot-image.i386.img: knetbsd.image.i386 $(VAS_EBOOT_PAYLOADS_DIR)/knetbsd.miniroot.i386
|
||||
$(TARGET_OBJCOPY) --add-section=miniroot=$< $(VAS_EBOOT_PAYLOADS_DIR)/knetbsd.miniroot.i386 $@
|
||||
|
||||
kfreebsd-mfsroot.x86_64.img: kfreebsd.init.x86_64 Makefile
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -t ffs -s 30m -f 1000 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||
|
||||
knetbsd.image.x86_64: knetbsd.init.x86_64 $(srcdir)/grub-core/tests/boot/kbsd.spec.txt
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/grub-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||
knetbsd.image.x86_64: knetbsd.init.x86_64 $(srcdir)/VasEBoot-core/tests/boot/kbsd.spec.txt
|
||||
TDIR=`mktemp -d "$${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"` && mkdir $$TDIR/dev && mkdir $$TDIR/sbin && cp $< $$TDIR/sbin/init && makefs -F $(srcdir)/VasEBoot-core/tests/boot/kbsd.spec.txt -t ffs -s 64k -f 10 -o minfree=0,version=1 $@ $$TDIR && rm -rf $$TDIR
|
||||
|
||||
knetbsd.miniroot-image.x86_64.img: knetbsd.image.x86_64 $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.x86_64
|
||||
$(TARGET_OBJCOPY) --add-section=miniroot=$< $(GRUB_PAYLOADS_DIR)/knetbsd.miniroot.x86_64 $@
|
||||
knetbsd.miniroot-image.x86_64.img: knetbsd.image.x86_64 $(VAS_EBOOT_PAYLOADS_DIR)/knetbsd.miniroot.x86_64
|
||||
$(TARGET_OBJCOPY) --add-section=miniroot=$< $(VAS_EBOOT_PAYLOADS_DIR)/knetbsd.miniroot.x86_64 $@
|
||||
|
||||
CLEANFILES += linux.init.i386 kfreebsd.init.i386 linux.init.x86_64 linux-initramfs.i386 linux-initramfs.x86_64
|
||||
|
||||
kfreebsd-mfsroot.i386.gz: kfreebsd-mfsroot.i386.img
|
||||
gzip < $< > $@
|
||||
|
||||
bootcheck-kfreebsd-i386: kfreebsd-mfsroot.i386.gz $(GRUB_PAYLOADS_DIR)/kfreebsd.i386 $(GRUB_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/mfsroot.gz=kfreebsd-mfsroot.i386.gz --files=/kfreebsd=$(GRUB_PAYLOADS_DIR)/kfreebsd.i386 --files=/kfreebsd_env=$(GRUB_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-kfreebsd-i386: kfreebsd-mfsroot.i386.gz $(VAS_EBOOT_PAYLOADS_DIR)/kfreebsd.i386 $(VAS_EBOOT_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/VasEBoot-core/tests/boot/kfreebsd.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/mfsroot.gz=kfreebsd-mfsroot.i386.gz --files=/kfreebsd=$(VAS_EBOOT_PAYLOADS_DIR)/kfreebsd.i386 --files=/kfreebsd_env=$(VAS_EBOOT_PAYLOADS_DIR)/kfreebsd_env.i386 $(srcdir)/VasEBoot-core/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
kfreebsd-mfsroot.x86_64.gz: kfreebsd-mfsroot.x86_64.img
|
||||
gzip < $< > $@
|
||||
|
||||
bootcheck-kfreebsd-x86_64: kfreebsd-mfsroot.x86_64.gz $(GRUB_PAYLOADS_DIR)/kfreebsd.x86_64 $(GRUB_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/mfsroot.gz=kfreebsd-mfsroot.x86_64.gz --files=/kfreebsd=$(GRUB_PAYLOADS_DIR)/kfreebsd.x86_64 --files=/kfreebsd_env=$(GRUB_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/grub-core/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-kfreebsd-x86_64: kfreebsd-mfsroot.x86_64.gz $(VAS_EBOOT_PAYLOADS_DIR)/kfreebsd.x86_64 $(VAS_EBOOT_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/VasEBoot-core/tests/boot/kfreebsd.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/mfsroot.gz=kfreebsd-mfsroot.x86_64.gz --files=/kfreebsd=$(VAS_EBOOT_PAYLOADS_DIR)/kfreebsd.x86_64 --files=/kfreebsd_env=$(VAS_EBOOT_PAYLOADS_DIR)/kfreebsd_env.x86_64 $(srcdir)/VasEBoot-core/tests/boot/kfreebsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
knetbsd.miniroot-image.i386.gz: knetbsd.miniroot-image.i386.img
|
||||
gzip < $< > $@
|
||||
|
||||
bootcheck-knetbsd-i386: knetbsd.miniroot-image.i386.gz $(GRUB_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/grub-core/tests/boot/knetbsd.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/miniroot.gz=knetbsd.miniroot-image.i386.gz --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/grub-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-knetbsd-i386: knetbsd.miniroot-image.i386.gz $(VAS_EBOOT_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/VasEBoot-core/tests/boot/knetbsd.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/miniroot.gz=knetbsd.miniroot-image.i386.gz --files=/knetbsd=$(VAS_EBOOT_PAYLOADS_DIR)/knetbsd.i386 $(srcdir)/VasEBoot-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-kopenbsd-i386: kopenbsd.image.i386 $(GRUB_PAYLOADS_DIR)/kopenbsd.i386 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/ramdisk=kopenbsd.image.i386 --files=/kopenbsd=$(GRUB_PAYLOADS_DIR)/kopenbsd.i386 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-kopenbsd-i386: kopenbsd.image.i386 $(VAS_EBOOT_PAYLOADS_DIR)/kopenbsd.i386 $(srcdir)/VasEBoot-core/tests/boot/kopenbsd.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/ramdisk=kopenbsd.image.i386 --files=/kopenbsd=$(VAS_EBOOT_PAYLOADS_DIR)/kopenbsd.i386 $(srcdir)/VasEBoot-core/tests/boot/kopenbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-kopenbsd-x86_64: kopenbsd.image.x86_64 $(GRUB_PAYLOADS_DIR)/kopenbsd.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/ramdisk=kopenbsd.image.x86_64 --files=/kopenbsd=$(GRUB_PAYLOADS_DIR)/kopenbsd.x86_64 $(srcdir)/grub-core/tests/boot/kopenbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-kopenbsd-x86_64: kopenbsd.image.x86_64 $(VAS_EBOOT_PAYLOADS_DIR)/kopenbsd.x86_64 $(srcdir)/VasEBoot-core/tests/boot/kopenbsd.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/ramdisk=kopenbsd.image.x86_64 --files=/kopenbsd=$(VAS_EBOOT_PAYLOADS_DIR)/kopenbsd.x86_64 $(srcdir)/VasEBoot-core/tests/boot/kopenbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
knetbsd.miniroot-image.x86_64.gz: knetbsd.miniroot-image.x86_64.img
|
||||
gzip < $< > $@
|
||||
|
||||
bootcheck-knetbsd-x86_64: knetbsd.miniroot-image.x86_64.gz $(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/grub-core/tests/boot/knetbsd.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/miniroot.gz=knetbsd.miniroot-image.x86_64.gz --files=/knetbsd=$(GRUB_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/grub-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-knetbsd-x86_64: knetbsd.miniroot-image.x86_64.gz $(VAS_EBOOT_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/VasEBoot-core/tests/boot/knetbsd.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/miniroot.gz=knetbsd.miniroot-image.x86_64.gz --files=/knetbsd=$(VAS_EBOOT_PAYLOADS_DIR)/knetbsd.x86_64 $(srcdir)/VasEBoot-core/tests/boot/knetbsd.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg --qemu-opts="-cpu $(MINIMUM_CPU_LINUX)" | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-linux-i386: linux-initramfs.i386 $(VAS_EBOOT_PAYLOADS_DIR)/linux.i386 $(srcdir)/VasEBoot-core/tests/boot/linux.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(VAS_EBOOT_PAYLOADS_DIR)/linux.i386 $(srcdir)/VasEBoot-core/tests/boot/linux.cfg --qemu-opts="-cpu $(MINIMUM_CPU_LINUX)" | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-linux-x86_64: linux-initramfs.x86_64 $(VAS_EBOOT_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/VasEBoot-core/tests/boot/linux.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(VAS_EBOOT_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/VasEBoot-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux-mips: linux-initramfs.mips $(GRUB_PAYLOADS_DIR)/linux.mips $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.mips --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.mips $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-linux-mips: linux-initramfs.mips $(VAS_EBOOT_PAYLOADS_DIR)/linux.mips $(srcdir)/VasEBoot-core/tests/boot/linux.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.mips --files=/linux=$(VAS_EBOOT_PAYLOADS_DIR)/linux.mips $(srcdir)/VasEBoot-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux-ppc: linux-initramfs.ppc $(GRUB_PAYLOADS_DIR)/linux.ppc $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.ppc --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.ppc $(srcdir)/grub-core/tests/boot/linux-ppc.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-linux-ppc: linux-initramfs.ppc $(VAS_EBOOT_PAYLOADS_DIR)/linux.ppc $(srcdir)/VasEBoot-core/tests/boot/linux.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.ppc --files=/linux=$(VAS_EBOOT_PAYLOADS_DIR)/linux.ppc $(srcdir)/VasEBoot-core/tests/boot/linux-ppc.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux-mipsel: linux-initramfs.mipsel $(GRUB_PAYLOADS_DIR)/linux.mipsel $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.mipsel --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.mipsel $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-linux-mipsel: linux-initramfs.mipsel $(VAS_EBOOT_PAYLOADS_DIR)/linux.mipsel $(srcdir)/VasEBoot-core/tests/boot/linux.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.mipsel --files=/linux=$(VAS_EBOOT_PAYLOADS_DIR)/linux.mipsel $(srcdir)/VasEBoot-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux-loongson: linux-initramfs.loongson $(GRUB_PAYLOADS_DIR)/linux.loongson $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.loongson --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.loongson $(srcdir)/grub-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-linux-loongson: linux-initramfs.loongson $(VAS_EBOOT_PAYLOADS_DIR)/linux.loongson $(srcdir)/VasEBoot-core/tests/boot/linux.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --files=/initrd=linux-initramfs.loongson --files=/linux=$(VAS_EBOOT_PAYLOADS_DIR)/linux.loongson $(srcdir)/VasEBoot-core/tests/boot/linux.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux16-i386: linux-initramfs.i386 $(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.i386 $(srcdir)/grub-core/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-linux16-i386: linux-initramfs.i386 $(VAS_EBOOT_PAYLOADS_DIR)/linux.i386 $(srcdir)/VasEBoot-core/tests/boot/linux.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/initrd=linux-initramfs.i386 --files=/linux=$(VAS_EBOOT_PAYLOADS_DIR)/linux.i386 $(srcdir)/VasEBoot-core/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-linux16-x86_64: linux-initramfs.x86_64 $(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(GRUB_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/grub-core/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-linux16-x86_64: linux-initramfs.x86_64 $(VAS_EBOOT_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/VasEBoot-core/tests/boot/linux.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=qemu-system-x86_64 --files=/initrd=linux-initramfs.x86_64 --files=/linux=$(VAS_EBOOT_PAYLOADS_DIR)/linux.x86_64 $(srcdir)/VasEBoot-core/tests/boot/linux16.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-multiboot: multiboot.elf $(srcdir)/grub-core/tests/boot/multiboot.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/multiboot.elf=multiboot.elf $(srcdir)/grub-core/tests/boot/multiboot.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-multiboot: multiboot.elf $(srcdir)/VasEBoot-core/tests/boot/multiboot.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/multiboot.elf=multiboot.elf $(srcdir)/VasEBoot-core/tests/boot/multiboot.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-multiboot2: multiboot2.elf $(srcdir)/grub-core/tests/boot/multiboot2.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/multiboot2.elf=multiboot2.elf $(srcdir)/grub-core/tests/boot/multiboot2.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-multiboot2: multiboot2.elf $(srcdir)/VasEBoot-core/tests/boot/multiboot2.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/multiboot2.elf=multiboot2.elf $(srcdir)/VasEBoot-core/tests/boot/multiboot2.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-kfreebsd-aout: kfreebsd.aout $(srcdir)/grub-core/tests/boot/kfreebsd-aout.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/kfreebsd.aout=kfreebsd.aout $(srcdir)/grub-core/tests/boot/kfreebsd-aout.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-kfreebsd-aout: kfreebsd.aout $(srcdir)/VasEBoot-core/tests/boot/kfreebsd-aout.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/kfreebsd.aout=kfreebsd.aout $(srcdir)/VasEBoot-core/tests/boot/kfreebsd-aout.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-pc-chainloader: pc-chainloader.bin $(srcdir)/grub-core/tests/boot/pc-chainloader.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/pc-chainloader.bin=pc-chainloader.bin $(srcdir)/grub-core/tests/boot/pc-chainloader.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-pc-chainloader: pc-chainloader.bin $(srcdir)/VasEBoot-core/tests/boot/pc-chainloader.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/pc-chainloader.bin=pc-chainloader.bin $(srcdir)/VasEBoot-core/tests/boot/pc-chainloader.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
bootcheck-ntldr: ntldr.bin $(srcdir)/grub-core/tests/boot/ntldr.cfg grub-shell
|
||||
./grub-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/ntldr.bin=ntldr.bin $(srcdir)/grub-core/tests/boot/ntldr.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
bootcheck-ntldr: ntldr.bin $(srcdir)/VasEBoot-core/tests/boot/ntldr.cfg VasEBoot-shell
|
||||
./VasEBoot-shell --timeout=$(BOOTCHECK_TIMEOUT) --qemu=$(QEMU32) --files=/ntldr.bin=ntldr.bin $(srcdir)/VasEBoot-core/tests/boot/ntldr.cfg | grep $(SUCCESSFUL_BOOT_STRING) > /dev/null
|
||||
|
||||
if COND_i386_efi
|
||||
# NetBSD has no support for finding ACPI on EFI
|
||||
|
|
@ -422,21 +431,22 @@ BOOTCHECK_TIMEOUT=180
|
|||
bootcheck: $(BOOTCHECKS)
|
||||
|
||||
if COND_i386_coreboot
|
||||
default_payload.elf: grub-mkstandalone grub-mkimage FORCE
|
||||
FS_PAYLOAD_MODULES ?= $(shell cat VasEBoot-core/fs.lst)
|
||||
default_payload.elf: VasEBoot-mkstandalone VasEBoot-mkimage FORCE
|
||||
test -f $@ && rm $@ || true
|
||||
pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(shell cat grub-core/fs.lst) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
|
||||
pkgdatadir=. ./VasEBoot-mkstandalone --VasEBoot-mkimage=./VasEBoot-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d VasEBoot-core/ /boot/VasEBoot/VasEBoot.cfg=$(srcdir)/coreboot.cfg
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
EXTRA_DIST += grub-core/tests/boot/kbsd.init-i386.S grub-core/tests/boot/kbsd.init-x86_64.S grub-core/tests/boot/kbsd.spec.txt grub-core/tests/boot/kernel-8086.S grub-core/tests/boot/kernel-i386.S grub-core/tests/boot/kfreebsd-aout.cfg grub-core/tests/boot/kfreebsd.cfg grub-core/tests/boot/kfreebsd.init-i386.S grub-core/tests/boot/kfreebsd.init-x86_64.S grub-core/tests/boot/knetbsd.cfg grub-core/tests/boot/kopenbsd.cfg grub-core/tests/boot/kopenbsdlabel.txt grub-core/tests/boot/linux16.cfg grub-core/tests/boot/linux.cfg grub-core/tests/boot/linux.init-i386.S grub-core/tests/boot/linux.init-mips.S grub-core/tests/boot/linux.init-ppc.S grub-core/tests/boot/linux.init-x86_64.S grub-core/tests/boot/linux-ppc.cfg grub-core/tests/boot/multiboot2.cfg grub-core/tests/boot/multiboot.cfg grub-core/tests/boot/ntldr.cfg grub-core/tests/boot/pc-chainloader.cfg grub-core/tests/boot/qemu-shutdown-x86.S
|
||||
EXTRA_DIST += VasEBoot-core/tests/boot/kbsd.init-i386.S VasEBoot-core/tests/boot/kbsd.init-x86_64.S VasEBoot-core/tests/boot/kbsd.spec.txt VasEBoot-core/tests/boot/kernel-8086.S VasEBoot-core/tests/boot/kernel-i386.S VasEBoot-core/tests/boot/kfreebsd-aout.cfg VasEBoot-core/tests/boot/kfreebsd.cfg VasEBoot-core/tests/boot/kfreebsd.init-i386.S VasEBoot-core/tests/boot/kfreebsd.init-x86_64.S VasEBoot-core/tests/boot/knetbsd.cfg VasEBoot-core/tests/boot/kopenbsd.cfg VasEBoot-core/tests/boot/kopenbsdlabel.txt VasEBoot-core/tests/boot/linux16.cfg VasEBoot-core/tests/boot/linux.cfg VasEBoot-core/tests/boot/linux.init-i386.S VasEBoot-core/tests/boot/linux.init-mips.S VasEBoot-core/tests/boot/linux.init-ppc.S VasEBoot-core/tests/boot/linux.init-x86_64.S VasEBoot-core/tests/boot/linux-ppc.cfg VasEBoot-core/tests/boot/multiboot2.cfg VasEBoot-core/tests/boot/multiboot.cfg VasEBoot-core/tests/boot/ntldr.cfg VasEBoot-core/tests/boot/pc-chainloader.cfg VasEBoot-core/tests/boot/qemu-shutdown-x86.S
|
||||
|
||||
windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows
|
||||
windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
|
||||
test -d $(windowsdir) && rm -rf $(windowsdir) || true
|
||||
test -d $(windowsdir) || mkdir $(windowsdir)
|
||||
$(MAKE) -C po $(AM_MAKEFLAGS) windowsdir
|
||||
$(MAKE) -C grub-core $(AM_MAKEFLAGS) windowsdir
|
||||
$(MAKE) -C VasEBoot-core $(AM_MAKEFLAGS) windowsdir
|
||||
test -d $(windowsdir)/themes || mkdir $(windowsdir)/themes
|
||||
test -d $(windowsdir)/themes/starfield || mkdir $(windowsdir)/themes/starfield
|
||||
for x in $(PROGRAMS); do \
|
||||
|
|
@ -449,7 +459,7 @@ windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
|
|||
for x in $(starfield_DATA); do \
|
||||
cp -fp $$x $(windowsdir)/themes/starfield/$$(basename $$x); \
|
||||
done
|
||||
for x in $(GRUB_WINDOWS_EXTRA_DIST); do \
|
||||
for x in $(VAS_EBOOT_WINDOWS_EXTRA_DIST); do \
|
||||
cp -fp $$x $(windowsdir); \
|
||||
done
|
||||
|
||||
|
|
@ -472,10 +482,13 @@ ChangeLog: FORCE
|
|||
touch $@; \
|
||||
fi
|
||||
|
||||
EXTRA_DIST += ChangeLog ChangeLog-2015
|
||||
syslinux_test: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_VasEBoot.cfg
|
||||
|
||||
syslinux_test: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg
|
||||
|
||||
tests/syslinux/ubuntu10.04_grub.cfg: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_grub.cfg.in
|
||||
(for x in tests/syslinux/ubuntu10.04_grub.cfg.in ; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:-
|
||||
CLEANFILES += tests/syslinux/ubuntu10.04_grub.cfg
|
||||
# Mimic simplify_filename from VasEBoot-core/lib/syslinux_parse.c, so that we
|
||||
# can predict its behaviour in tests. We have to pre-substitute this before
|
||||
# calling config.status, as config.status offers no reliable way to hook in
|
||||
# a command between setting ac_abs_top_srcdir and emitting output files.
|
||||
tests/syslinux/ubuntu10.04_VasEBoot.cfg: $(top_builddir)/config.status tests/syslinux/ubuntu10.04_VasEBoot.cfg.in
|
||||
simplified_abs_top_srcdir=`echo "$(abs_top_srcdir)" | sed 's,//,/,g; s,/\./,/,g; :loop; s,/[^/][^/]*/\.\.\(/\|$$\),\1,; t loop'`; \
|
||||
sed "s,@simplified_abs_top_srcdir@,$$simplified_abs_top_srcdir,g" $(srcdir)/tests/syslinux/ubuntu10.04_VasEBoot.cfg.in | $(top_builddir)/config.status --file=$@:-
|
||||
CLEANFILES += tests/syslinux/ubuntu10.04_VasEBoot.cfg
|
||||
|
|
|
|||
1478
Makefile.util.def
1478
Makefile.util.def
File diff suppressed because it is too large
Load Diff
239
NEWS
239
NEWS
|
|
@ -1,3 +1,82 @@
|
|||
New in 2.14.1:
|
||||
|
||||
* Small fix in VasEBoot-core/normal/main.c
|
||||
|
||||
New in 2.14:
|
||||
|
||||
* libgcrypt 1.11.
|
||||
* LVM LV integrity and cachevol support.
|
||||
* EROFS support.
|
||||
* VAS_EBOOT environment block inside the Btrfs header support.
|
||||
* NX support for EFI platforms.
|
||||
* shim loader protocol support.
|
||||
* BLS and UKI support.
|
||||
* Argon2 KDF support.
|
||||
* TPM2 key protector support.
|
||||
* Appended Signature Secure Boot Support for PowerPC.
|
||||
* New option to block command line interface.
|
||||
* Support dates outside of 1901..2038 range.
|
||||
* zstdio decompression support.
|
||||
* EFI code improvements and fixes.
|
||||
* TPM driver fixes.
|
||||
* Filesystems fixes.
|
||||
* CVE and Coverity fixes.
|
||||
* Tests improvements.
|
||||
* Documentation improvements.
|
||||
* ... and tons of other fixes and cleanups...
|
||||
|
||||
New in 2.12:
|
||||
|
||||
* GCC 13 support.
|
||||
* clang 14 support.
|
||||
* binutils 2.38 support.
|
||||
* Unification of EFI Linux kernel loader across architectures.
|
||||
* Transition to EFI Linux kernel stub loader for x86 architecture.
|
||||
* Initial support for Boot Loader Interface.
|
||||
* Support for dynamic VAS_EBOOT runtime memory addition using firmware calls.
|
||||
* PCI and MMIO UARTs support.
|
||||
* SDL2 support.
|
||||
* LoongArch support.
|
||||
* TPM driver fixes.
|
||||
* Many filesystems fixes.
|
||||
* Many CVE and Coverity fixes.
|
||||
* Debugging support improvements.
|
||||
* Tests improvements.
|
||||
* Documentation improvements.
|
||||
* ...and tons of other fixes and cleanups...
|
||||
|
||||
New in 2.06:
|
||||
|
||||
* GCC 10 support.
|
||||
* clang 10 support.
|
||||
* SBAT support.
|
||||
* LUKS2 support.
|
||||
* Drop small MBR gap support.
|
||||
* Xen Security Modules (XSM/FLASK) support.
|
||||
* The lockdown mechanism similar to the Linux kernel one.
|
||||
* Disable the os-prober by default.
|
||||
* Many backports of VAS_EBOOT distros specific patches.
|
||||
* BootHole and BootHole2 fixes.
|
||||
* ...and tons of other fixes and cleanups...
|
||||
|
||||
New in 2.04:
|
||||
|
||||
* GCC 8 and 9 support.
|
||||
* Gnulib integration overhaul.
|
||||
* RISC-V support.
|
||||
* Xen PVH support.
|
||||
* Native UEFI secure boot support.
|
||||
* UEFI TPM driver.
|
||||
* New IEEE 1275 obdisk driver.
|
||||
* Btrfs RAID 5 and RIAD 6 support.
|
||||
* PARTUUID support.
|
||||
* VLAN support.
|
||||
* Native DHCP support.
|
||||
* Many ARM and ARM64 fixes.
|
||||
* Many SPARC fixes.
|
||||
* Many IEEE 1275 fixes.
|
||||
* ...and tons of other fixes and cleanups...
|
||||
|
||||
New in 2.02:
|
||||
|
||||
* New/improved filesystem and disk support:
|
||||
|
|
@ -21,13 +100,13 @@ New in 2.02:
|
|||
* LVM RAID1 support.
|
||||
|
||||
* New/improved terminal and video support:
|
||||
* Monochrome text (matching `hercules' in GRUB Legacy).
|
||||
* Monochrome text (matching `hercules' in VAS_EBOOT Legacy).
|
||||
* Morse code output using system speaker.
|
||||
* `spkmodem' output (simple data protocol using system speaker).
|
||||
* Handle Japanese special keys.
|
||||
* coreboot framebuffer.
|
||||
* Serial on ARC.
|
||||
* Native vt100 handling for grub-emu, replacing the use of the curses
|
||||
* Native vt100 handling for VasEBoot-emu, replacing the use of the curses
|
||||
library.
|
||||
* New gfxmenu options for terminal window positioning, theme background
|
||||
image handling, and scrollbar padding, plus `item_pixmap_style' and
|
||||
|
|
@ -48,7 +127,7 @@ New in 2.02:
|
|||
interface.
|
||||
* Autoload `http' and `tftp' modules if necessary.
|
||||
* Improve TFTP robustness.
|
||||
* Parse `nd' disk names in GRUB Legacy configuration files.
|
||||
* Parse `nd' disk names in VAS_EBOOT Legacy configuration files.
|
||||
* Issue separate DNS queries for IPv4 and IPv6.
|
||||
* Support IPv6 Router Advertisement to configure default router.
|
||||
* New variable net_<interface>_next_server containing next server
|
||||
|
|
@ -71,11 +150,11 @@ New in 2.02:
|
|||
* New command `pcidump' for PCI platforms.
|
||||
* Improve opcode parsing in ACPI halt implementation.
|
||||
* Use the TSC as a possible time source on i386-ieee1275.
|
||||
* Merge PowerPC grub-mkrescue implementation with the common one.
|
||||
* Support grub-mkrescue on i386-ieee1275, sparc64, bootinfo machines such
|
||||
* Merge PowerPC VasEBoot-mkrescue implementation with the common one.
|
||||
* Support VasEBoot-mkrescue on i386-ieee1275, sparc64, bootinfo machines such
|
||||
as pSeries, and mips-arc.
|
||||
* Make grub-mkrescue better support Apple Intel Macs on CD.
|
||||
* Enable GRUB Legacy configuration file parsing on EFI.
|
||||
* Make VasEBoot-mkrescue better support Apple Intel Macs on CD.
|
||||
* Enable VAS_EBOOT Legacy configuration file parsing on EFI.
|
||||
* Support halt for Loongson 2E.
|
||||
* ARM U-Boot and EFI ports.
|
||||
* Reorganise platform-dependent code in utilities to avoid #ifdef mess.
|
||||
|
|
@ -84,8 +163,8 @@ New in 2.02:
|
|||
* Fix EFI stack alignment.
|
||||
* ARM64 EFI port.
|
||||
* On Linux, read partition start offsets from sysfs if possible.
|
||||
* New grub-macbless utility, and better integration with Mac firmware in
|
||||
grub-install.
|
||||
* New VasEBoot-macbless utility, and better integration with Mac firmware in
|
||||
VasEBoot-install.
|
||||
* Support Yeeloong 3A.
|
||||
* Add `cpuid --pae' option to detect Physical Address Extension on x86.
|
||||
* Support for USB debug dongles.
|
||||
|
|
@ -118,36 +197,36 @@ New in 2.02:
|
|||
|
||||
* Scripting:
|
||||
* New `eval' and `tr' commands.
|
||||
* grub-script-check fails on scripts containing no commands.
|
||||
* VasEBoot-script-check fails on scripts containing no commands.
|
||||
|
||||
* Installation and other utility improvements:
|
||||
* Add option to compress files on installation or image creation.
|
||||
* Using grub-reboot no longer requires setting `GRUB_DEFAULT=saved'.
|
||||
* Using VasEBoot-reboot no longer requires setting `VAS_EBOOT_DEFAULT=saved'.
|
||||
* Support probing EFI System Partition (requires os-prober >= 1.58).
|
||||
* Fix inconsistent use of `GRUB_CRYPTODISK_ENABLE' and
|
||||
`GRUB_ENABLE_CRYPTODISK'; the latter is now used consistently.
|
||||
* grub-mount handles symbolic links to directories.
|
||||
* Support disabling submenus with `GRUB_DISABLE_SUBMENU' configuration key
|
||||
for grub-mkconfig.
|
||||
* grub-install, grub-mknetdir, grub-mkrescue, and grub-mkstandalone
|
||||
* Fix inconsistent use of `VAS_EBOOT_CRYPTODISK_ENABLE' and
|
||||
`VAS_EBOOT_ENABLE_CRYPTODISK'; the latter is now used consistently.
|
||||
* VasEBoot-mount handles symbolic links to directories.
|
||||
* Support disabling submenus with `VAS_EBOOT_DISABLE_SUBMENU' configuration key
|
||||
for VasEBoot-mkconfig.
|
||||
* VasEBoot-install, VasEBoot-mknetdir, VasEBoot-mkrescue, and VasEBoot-mkstandalone
|
||||
rewritten in C. They should now work in supported non-Unix-like
|
||||
environments.
|
||||
* Native mingw support.
|
||||
* Ability to install on EFI under windows.
|
||||
* Reorganise timeout handling using new `timeout_style' environment
|
||||
variable and `GRUB_TIMEOUT_STYLE' configuration key for grub-mkconfig.
|
||||
variable and `VAS_EBOOT_TIMEOUT_STYLE' configuration key for VasEBoot-mkconfig.
|
||||
Menu hotkeys pressed during a hidden timeout now boot the corresponding
|
||||
menu entry immediately.
|
||||
* New `file' command and grub-file utility to check file types.
|
||||
* New `file' command and VasEBoot-file utility to check file types.
|
||||
* New syslinux configuration file parser.
|
||||
* Set menu entry class to primary OS name returned by os-prober to display
|
||||
OS specific icon.
|
||||
* On Linux x86 detect EFI word size in grub-install and automatically select
|
||||
* On Linux x86 detect EFI word size in VasEBoot-install and automatically select
|
||||
correct platform (x86_64-efi or i386-efi) to install. Requires Linux kernel
|
||||
4.0 or higher.
|
||||
|
||||
* Build system:
|
||||
* Remove all uses of nested functions; GRUB no longer requires an
|
||||
* Remove all uses of nested functions; VAS_EBOOT no longer requires an
|
||||
executable stack.
|
||||
* Fix documentation build with Texinfo >= 5.1.
|
||||
* More robust and documented cross-compiling support.
|
||||
|
|
@ -155,7 +234,7 @@ New in 2.02:
|
|||
* Partial mingw64 x86_64-efi compile support (highly experimental).
|
||||
* Partial mingw32 i386-* (other than already present i386-pc)
|
||||
compile support (highly experimental).
|
||||
* Support for grub-mkpasswd on Windows.
|
||||
* Support for VasEBoot-mkpasswd on Windows.
|
||||
* Eliminate the use of AutoGen. This allowed some performance
|
||||
improvements to the build system.
|
||||
* Remove variable length arrays.
|
||||
|
|
@ -170,7 +249,7 @@ New in 2.02:
|
|||
system.
|
||||
* emu libusb support removed (was broken and unmaintained).
|
||||
* powerpc64le compile support.
|
||||
* Use fixed timestamp when generating GRUB image for reproducible builds.
|
||||
* Use fixed timestamp when generating VAS_EBOOT image for reproducible builds.
|
||||
* Verify at build time that modules contain only supported relocations and their
|
||||
structure matches what boot-time module loader expects.
|
||||
* Do not require fonts on powerpc-ieee1275.
|
||||
|
|
@ -186,12 +265,12 @@ New in 2.00:
|
|||
|
||||
* New platforms:
|
||||
* Itanium port.
|
||||
* Fuloong2F support (including GRUB as firmware)
|
||||
* Fuloong2E support (except GRUB as firmware)
|
||||
* Fuloong2F support (including VAS_EBOOT as firmware)
|
||||
* Fuloong2E support (except VAS_EBOOT as firmware)
|
||||
* ARCS (SGI machines) port.
|
||||
* qemu -M mips port.
|
||||
|
||||
* grub-mount to mount filesystems using GRUB FS drivers and FUSE.
|
||||
* VasEBoot-mount to mount filesystems using VAS_EBOOT FS drivers and FUSE.
|
||||
|
||||
* Changed security default so entries are locked by default if any superuser is
|
||||
defined.
|
||||
|
|
@ -250,8 +329,8 @@ New in 2.00:
|
|||
* Basic illumos and xnu autoconfig.
|
||||
|
||||
* Testing and debugging:
|
||||
* New grub-fstest commands: cat, zfsinfo, testload xnu_uuid
|
||||
* grub-fstest recursive directory compare for quickly checking that
|
||||
* New VasEBoot-fstest commands: cat, zfsinfo, testload xnu_uuid
|
||||
* VasEBoot-fstest recursive directory compare for quickly checking that
|
||||
a directory is read correctly.
|
||||
* Backtace on crash (if gdb module is loaded, x86 only)
|
||||
* Disk cache statistics gathering.
|
||||
|
|
@ -269,12 +348,12 @@ New in 2.00:
|
|||
|
||||
* Internationalisation:
|
||||
* Updated to Unicode 6.0.
|
||||
* $"..." syntax for translation in grub scripting language. This allows easy
|
||||
translation of grub.cfg at runtime.
|
||||
* $"..." syntax for translation in VasEBoot scripting language. This allows easy
|
||||
translation of VasEBoot.cfg at runtime.
|
||||
* Translations to many languages included in official distribution.
|
||||
|
||||
* Scripting:
|
||||
* $grub_cpu and $grub_platform variables for conditioning grub.cfg on platform
|
||||
* $VasEBoot_cpu and $VasEBoot_platform variables for conditioning VasEBoot.cfg on platform
|
||||
at runtime.
|
||||
* $feature_* variables to condition scripts on available features.
|
||||
* Use of ids to identify menu entries.
|
||||
|
|
@ -282,16 +361,16 @@ New in 2.00:
|
|||
allowing easy loading of all of them.
|
||||
|
||||
* Installation:
|
||||
* grub-mknetdir script for easy creation of netbootable GRUB directory.
|
||||
* Itanium and mips support in grub-mkrescue.
|
||||
* grub-install support for all platforms except emu.
|
||||
* VasEBoot-mknetdir script for easy creation of netbootable VAS_EBOOT directory.
|
||||
* Itanium and mips support in VasEBoot-mkrescue.
|
||||
* VasEBoot-install support for all platforms except emu.
|
||||
* PreP partition install support.
|
||||
* No files conflict between flavours (except grub-mkrescue for ppc). This
|
||||
allows easy install of GRUB for several platforms.
|
||||
* grub-mkstandalone script for easy creating of image including all modules
|
||||
* No files conflict between flavours (except VasEBoot-mkrescue for ppc). This
|
||||
allows easy install of VAS_EBOOT for several platforms.
|
||||
* VasEBoot-mkstandalone script for easy creating of image including all modules
|
||||
for platforms with generous limit on image size.
|
||||
* program-transform-name now functions according to usual conventions.
|
||||
Use --grubdir and --bootdir to get old behaviour.
|
||||
Use --VasEBootdir and --bootdir to get old behaviour.
|
||||
|
||||
* ADLER32 and CRC64 support (for XZ and hashsum).
|
||||
|
||||
|
|
@ -299,8 +378,8 @@ New in 2.00:
|
|||
|
||||
* Experimental support for compiling with Apple toolchain.
|
||||
|
||||
* grub-mkdevicemap removed. Now all devices are detected on invocation of
|
||||
any grub utility.
|
||||
* VasEBoot-mkdevicemap removed. Now all devices are detected on invocation of
|
||||
any VasEBoot utility.
|
||||
|
||||
New in 1.99:
|
||||
|
||||
|
|
@ -308,7 +387,7 @@ New in 1.99:
|
|||
|
||||
* New `lsapm' command (i386-pc only).
|
||||
|
||||
* Parser for GRUB Legacy configuration files.
|
||||
* Parser for VAS_EBOOT Legacy configuration files.
|
||||
|
||||
* Support RAID on virtio devices.
|
||||
|
||||
|
|
@ -327,7 +406,7 @@ New in 1.99:
|
|||
listed in device.map will be assumed to be readable using only BIOS
|
||||
facilities, rather than anything more complex such as LVM or RAID.
|
||||
|
||||
* New bash-completion script for GRUB utilities.
|
||||
* New bash-completion script for VAS_EBOOT utilities.
|
||||
|
||||
* Use ACPI to shut down if possible.
|
||||
|
||||
|
|
@ -335,15 +414,15 @@ New in 1.99:
|
|||
|
||||
* Btrfs support.
|
||||
|
||||
* New `--boot-directory' option to `grub-install', `grub-reboot', and
|
||||
`grub-set-default', with clearer semantics than the previous
|
||||
* New `--boot-directory' option to `VasEBoot-install', `VasEBoot-reboot', and
|
||||
`VasEBoot-set-default', with clearer semantics than the previous
|
||||
`--root-directory' option.
|
||||
|
||||
* Rename CD-ROM device to "cd" on BIOS platforms.
|
||||
|
||||
* Transparent decompression filters.
|
||||
|
||||
* Simpler PXE image generation. New `grub-mknetdir' utility to generate
|
||||
* Simpler PXE image generation. New `VasEBoot-mknetdir' utility to generate
|
||||
netboot directory trees.
|
||||
|
||||
* New relocator. Allows for more kernel support and more
|
||||
|
|
@ -367,18 +446,18 @@ New in 1.99:
|
|||
|
||||
* MIPS Yeeloong firmware port.
|
||||
|
||||
* Change grub-mkdevicemap to emit /dev/disk/by-id/ names where possible
|
||||
* Change VasEBoot-mkdevicemap to emit /dev/disk/by-id/ names where possible
|
||||
on GNU/Linux.
|
||||
|
||||
* Add `grub-mkconfig' support for Xen with Linux.
|
||||
* Add `VasEBoot-mkconfig' support for Xen with Linux.
|
||||
|
||||
* Add `grub-mkconfig' support for initrd images on Fedora 13.
|
||||
* Add `VasEBoot-mkconfig' support for initrd images on Fedora 13.
|
||||
|
||||
* Support >3GiB and <16MiB RAM in i386-qemu.
|
||||
|
||||
* Add support for Cirrus 5446 and Bochs video cards.
|
||||
|
||||
* Load more appropriate video drivers automatically in `grub-mkconfig'.
|
||||
* Load more appropriate video drivers automatically in `VasEBoot-mkconfig'.
|
||||
|
||||
* USB improvements, including hotplugging/hotunplugging, hub support,
|
||||
and USB serial support.
|
||||
|
|
@ -395,12 +474,12 @@ New in 1.99:
|
|||
|
||||
* Add support for DM-RAID disk devices on GNU/Linux.
|
||||
|
||||
* Remove `grub-mkisofs'. `grub-mkrescue' now uses GNU xorriso to build
|
||||
* Remove `VasEBoot-mkisofs'. `VasEBoot-mkrescue' now uses GNU xorriso to build
|
||||
CD images.
|
||||
|
||||
* `grub-mkrescue' support for EFI, coreboot, and QEMU platforms.
|
||||
* `VasEBoot-mkrescue' support for EFI, coreboot, and QEMU platforms.
|
||||
|
||||
* Unify `grub-mkimage', `grub-setup', and `grub-install' source code
|
||||
* Unify `VasEBoot-mkimage', `VasEBoot-setup', and `VasEBoot-install' source code
|
||||
across platforms.
|
||||
|
||||
* Fix VGA (as opposed to VBE) video driver, formerly a terminal driver.
|
||||
|
|
@ -409,11 +488,11 @@ New in 1.99:
|
|||
|
||||
* Add support for the nilfs2 filesystem.
|
||||
|
||||
* `grub-probe' and `grub-mkconfig' support for NetBSD.
|
||||
* `VasEBoot-probe' and `VasEBoot-mkconfig' support for NetBSD.
|
||||
|
||||
* Support setting a background image in `grub-mkconfig'.
|
||||
* Support setting a background image in `VasEBoot-mkconfig'.
|
||||
|
||||
* Support multiple terminals in `grub-mkconfig'.
|
||||
* Support multiple terminals in `VasEBoot-mkconfig'.
|
||||
|
||||
* Regexp support.
|
||||
|
||||
|
|
@ -423,17 +502,17 @@ New in 1.99:
|
|||
|
||||
* sunpc partition table support.
|
||||
|
||||
* Add a number of new language features to GRUB script: `for', `while',
|
||||
* Add a number of new language features to VAS_EBOOT script: `for', `while',
|
||||
`until', `elif', function parameters, `break', `continue', `shift',
|
||||
multi-line quoted strings, positional parameters with `setparams',
|
||||
`return', filename wildcard expansion, and `!'.
|
||||
|
||||
* Support nested partition tables. GRUB now prefers to name partitions
|
||||
* Support nested partition tables. VAS_EBOOT now prefers to name partitions
|
||||
in the form `(hd0,msdos1,bsd1)' rather than `(hd0,1,a)'.
|
||||
|
||||
* Speed up consecutive hostdisk operations on the same device.
|
||||
|
||||
* Compile parts of `grub-emu' as modules.
|
||||
* Compile parts of `VasEBoot-emu' as modules.
|
||||
|
||||
New in 1.98 - 2010-03-06:
|
||||
|
||||
|
|
@ -443,18 +522,18 @@ New in 1.98 - 2010-03-06:
|
|||
|
||||
* MIPS support.
|
||||
|
||||
* Saved default menu entry support, with new utilities `grub-reboot' and
|
||||
`grub-set-default'.
|
||||
* Saved default menu entry support, with new utilities `VasEBoot-reboot' and
|
||||
`VasEBoot-set-default'.
|
||||
|
||||
* Unit testing framework.
|
||||
|
||||
* Support for multiple terminals.
|
||||
|
||||
* Encrypted password support, with a new utility `grub-mkpasswd-pbkdf2'.
|
||||
* Encrypted password support, with a new utility `VasEBoot-mkpasswd-pbkdf2'.
|
||||
|
||||
* `grub-mkfloppy' removed; use `grub-mkrescue' to create floppy images.
|
||||
* `VasEBoot-mkfloppy' removed; use `VasEBoot-mkrescue' to create floppy images.
|
||||
|
||||
* Add grub-probe support for GNU/Hurd.
|
||||
* Add VasEBoot-probe support for GNU/Hurd.
|
||||
|
||||
* Add support for gettext.
|
||||
|
||||
|
|
@ -482,7 +561,7 @@ New in 1.97:
|
|||
|
||||
* Add support for RAID levels 4,6 and 10.
|
||||
|
||||
* update-grub is replaced by grub-mkconfig.
|
||||
* update-VasEBoot is replaced by VasEBoot-mkconfig.
|
||||
|
||||
* When booting from PXE, PXE can be used to load files.
|
||||
|
||||
|
|
@ -510,7 +589,7 @@ New in 1.97:
|
|||
* Create partmap.lst and use it to automatically load partition map
|
||||
modules.
|
||||
|
||||
* grub-mkconfig supports os-prober to add operating systems to the
|
||||
* VasEBoot-mkconfig supports os-prober to add operating systems to the
|
||||
boot menu.
|
||||
|
||||
* The ATA driver supports devices bigger than 2 TiB.
|
||||
|
|
@ -525,26 +604,26 @@ New in 1.97:
|
|||
|
||||
* Support for direct access to AT keyboards.
|
||||
|
||||
* New utility `grub-fstest'.
|
||||
* New utility `VasEBoot-fstest'.
|
||||
|
||||
New in 1.96 - 2008-02-03:
|
||||
|
||||
* The license term is changed to GNU General Public License Version 3.
|
||||
|
||||
* grub-emu is made optional. Now you have to use
|
||||
`--enable-grub-emu' to enable it.
|
||||
* VasEBoot-emu is made optional. Now you have to use
|
||||
`--enable-VasEBoot-emu' to enable it.
|
||||
|
||||
* Add Multiboot2 support.
|
||||
|
||||
* grub-emu can access the host filesystem now.
|
||||
* VasEBoot-emu can access the host filesystem now.
|
||||
|
||||
* Add support for the NTFS, cpio/tar and Reiserfs filesystems.
|
||||
|
||||
* Add support for ATA/ATAPI.
|
||||
|
||||
* Add update-grub script to generate grub.cfg.
|
||||
* Add update-VasEBoot script to generate VasEBoot.cfg.
|
||||
|
||||
* Add grub-mkrescue script to generate floppy or ElTorito images
|
||||
* Add VasEBoot-mkrescue script to generate floppy or ElTorito images
|
||||
(i386-pc only).
|
||||
|
||||
* Add support for background images in gfxterm (background_image command).
|
||||
|
|
@ -553,7 +632,7 @@ New in 1.96 - 2008-02-03:
|
|||
|
||||
* GPT is now enabled in i386-pc target.
|
||||
|
||||
* Add grub-install for EFI.
|
||||
* Add VasEBoot-install for EFI.
|
||||
|
||||
* Ported to the following new platforms: Efika, coreboot (a.k.a. LinuxBIOS),
|
||||
OLPC XO.
|
||||
|
|
@ -568,8 +647,8 @@ New in 1.95 - 2006-10-15:
|
|||
* Number partitions from 1 instead of 0. For instance, the first
|
||||
partition of "hd0" is now "hd0,1" but not "hd0,0".
|
||||
|
||||
* grub-probefs is renamed to grub-probe, and supports printing a
|
||||
guessed OS device name and a GRUB drive name.
|
||||
* VasEBoot-probefs is renamed to VasEBoot-probe, and supports printing a
|
||||
guessed OS device name and a VAS_EBOOT drive name.
|
||||
|
||||
* RAID and LVM support is added.
|
||||
|
||||
|
|
@ -591,9 +670,9 @@ New in 1.94 - 2006-06-04:
|
|||
* Use --with-platform to specify a boot environment. For now, efi,
|
||||
ieee1275 and pc are supported.
|
||||
|
||||
* Use the filename "kernel.elf" instead of "grubof" on ieee1275.
|
||||
* Use the filename "kernel.elf" instead of "VasEBootof" on ieee1275.
|
||||
|
||||
* Install GRUB into pkglibdir instead of pkgdatadir.
|
||||
* Install VAS_EBOOT into pkglibdir instead of pkgdatadir.
|
||||
|
||||
* Support environmental variables. You can export variables by the
|
||||
command "export".
|
||||
|
|
@ -646,17 +725,17 @@ New in 1.91 - 2005-10-15:
|
|||
|
||||
* Add support for x86_64.
|
||||
|
||||
* GRUB itself is a Multiboot-compliant kernel.
|
||||
* VAS_EBOOT itself is a Multiboot-compliant kernel.
|
||||
|
||||
* Add new filesystems: XFS, SFS, and AFFS.
|
||||
|
||||
|
||||
New in 1.90 - 2005-08-07:
|
||||
|
||||
* Rename the project name PUPA to GRUB. Now this version is the
|
||||
developmental version of GRUB officially.
|
||||
* Rename the project name PUPA to VAS_EBOOT. Now this version is the
|
||||
developmental version of VAS_EBOOT officially.
|
||||
|
||||
* The GRUB emulator ``grub-emu'' is added.
|
||||
* The VAS_EBOOT emulator ``VasEBoot-emu'' is added.
|
||||
|
||||
* Add support for newworld Mac. This should work with other
|
||||
PowerPC-based machines as well, if they use IEEE 1275
|
||||
|
|
|
|||
24
README
24
README
|
|
@ -1,20 +1,26 @@
|
|||
This is GRUB 2, the second version of the GRand Unified Bootloader.
|
||||
GRUB 2 is rewritten from scratch to make GNU GRUB cleaner, safer, more
|
||||
This is VAS_EBOOT 2, the second version of the GRUB.
|
||||
VAS_EBOOT 2 is rewritten from scratch to make QNU VAS_EBOOT cleaner, safer, more
|
||||
robust, more powerful, and more portable.
|
||||
|
||||
See the file NEWS for a description of recent changes to GRUB 2.
|
||||
See the file NEWS for a description of recent changes to VAS_EBOOT 2.
|
||||
|
||||
See the file INSTALL for instructions on how to build and install the
|
||||
GRUB 2 data and program files.
|
||||
VAS_EBOOT 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>.
|
||||
See the file MAINTAINERS for information about the VAS_EBOOT maintainers, etc.
|
||||
|
||||
If you found a security vulnerability in the VAS_EBOOT please check the SECURITY
|
||||
file to get more information how to properly report this kind of bugs to
|
||||
the maintainers.
|
||||
|
||||
Please visit the official web page of VAS_EBOOT 2, for more information.
|
||||
The URL is <http://www.gnu.org/software/VasEBoot/VasEBoot.html>.
|
||||
|
||||
More extensive documentation is available in the Info manual,
|
||||
accessible using 'info grub' after building and installing GRUB 2.
|
||||
accessible using 'info VasEBoot' after building and installing VAS_EBOOT 2.
|
||||
|
||||
There are a number of important user-visible differences from the
|
||||
first version of GRUB, now known as GRUB Legacy. For a summary, please
|
||||
first version of VAS_EBOOT, now known as VAS_EBOOT Legacy. For a summary, please
|
||||
see:
|
||||
|
||||
info grub Introduction 'Changes from GRUB Legacy'
|
||||
info VasEBoot Introduction 'Changes from VAS_EBOOT Legacy'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
Security Policy
|
||||
===============
|
||||
|
||||
To report a vulnerability see "Reporting a Vulnerability" below.
|
||||
|
||||
|
||||
Security Incident Policy
|
||||
========================
|
||||
|
||||
Security bug reports are treated with special attention and are handled
|
||||
differently from normal bugs. In particular, security sensitive bugs are not
|
||||
handled in public but in private. Information about the bug and access to it
|
||||
is restricted to people in the security group, the individual engineers that
|
||||
work on fixing it, and any other person who needs to be involved for organisational
|
||||
reasons. The process is handled by the security team, which decides on the people
|
||||
involved in order to fix the issue. It is also guaranteed that the person reporting
|
||||
the issue has visibility into the process of fixing it. Any security issue gets
|
||||
prioritized according to its security rating. The issue is opened up to the public
|
||||
in coordination with the release schedule and the reporter.
|
||||
|
||||
|
||||
Disclosure Policy
|
||||
=================
|
||||
|
||||
Everyone involved in the handling of a security issue - including the reporter -
|
||||
is required to adhere to the following policy. Any information related to
|
||||
a security issue must be treated as confidential and only shared with trusted
|
||||
partners if necessary, for example to coordinate a release or manage exposure
|
||||
of clients to the issue. No information must be disclosed to the public before
|
||||
the embargo ends. The embargo time is agreed upon by all involved parties. It
|
||||
should be as short as possible without putting any users at risk.
|
||||
|
||||
|
||||
Supported Versions
|
||||
==================
|
||||
|
||||
Only the most recent version of the VAS_EBOOT is supported.
|
||||
|
||||
|
||||
Reporting a Vulnerability
|
||||
=========================
|
||||
|
||||
The security report should be encrypted with the PGP keys and sent to ALL email
|
||||
addresses listed below. Every vulnerability report will be assessed within
|
||||
72 hours of receiving it. If the outcome of the assessment is that the report
|
||||
describes a security issue, the report will be transferred into an issue on the
|
||||
internal vulnerability project for further processing. The reporter is updated
|
||||
on each step of the process.
|
||||
|
||||
While there's currently no bug bounty program we appreciate every report.
|
||||
|
||||
* Contact: Daniel Kiper <daniel.kiper@oracle.com> and
|
||||
Daniel Kiper <dkiper@net-space.pl>
|
||||
* PGP Key Fingerprint: BE5C 2320 9ACD DACE B20D B0A2 8C81 89F1 988C 2166
|
||||
|
||||
* Contact: Alex Burmashev <alexander.burmashev@oracle.com>
|
||||
* PGP Key Fingerprint: 50A4 EC06 EF7E B84D 67E0 3BB6 2AE2 C87E 28EF 2E6E
|
||||
|
||||
* Contact: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
|
||||
* PGP Key Fingerprint: E53D 497F 3FA4 2AD8 C9B4 D1E8 35A9 3B74 E82E 4209
|
||||
4
THANKS
4
THANKS
|
|
@ -1,10 +1,10 @@
|
|||
GRUB 2 would not be what it is today without the invaluable help of
|
||||
VAS_EBOOT 2 would not be what it is today without the invaluable help of
|
||||
everybody who was kind enough to spend time testing it and reporting
|
||||
bugs.
|
||||
|
||||
The following people made especially gracious contributions of their
|
||||
time and energy in helping to track down bugs, add new features, and
|
||||
generally assist in the GRUB 2 maintainership process:
|
||||
generally assist in the VAS_EBOOT 2 maintainership process:
|
||||
|
||||
Andrey Shuvikov <mr_hyro@yahoo.com>
|
||||
Bibo Mao <bibo.mao@intel.com>
|
||||
|
|
|
|||
8
TODO
8
TODO
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
Before working on improving GRUB, it's very important that you
|
||||
make contact with the core GRUB developers. Things herein might be
|
||||
Before working on improving VAS_EBOOT, it's very important that you
|
||||
make contact with the core VAS_EBOOT developers. Things herein might be
|
||||
slightly out of date or otherwise not easy to understand at first
|
||||
glance. So write to <grub-devel@gnu.org> first.
|
||||
glance. So write to <VasEBoot-devel@gnu.org> first.
|
||||
|
||||
For bug tracking, refer to:
|
||||
|
||||
http://savannah.gnu.org/bugs/?group=grub
|
||||
http://savannah.gnu.org/bugs/?group=VasEBoot
|
||||
|
|
|
|||
|
|
@ -0,0 +1,524 @@
|
|||
AUTOMAKE_OPTIONS = subdir-objects -Wno-portability
|
||||
|
||||
DEPDIR=.deps-core
|
||||
|
||||
include $(top_srcdir)/conf/Makefile.common
|
||||
|
||||
CC=$(TARGET_CC)
|
||||
CPP=$(TARGET_CC)
|
||||
CCAS=$(TARGET_CC)
|
||||
RANLIB=$(TARGET_RANLIB)
|
||||
STRIP=$(TARGET_STRIP)
|
||||
|
||||
MACHO2IMG=$(top_builddir)/VasEBoot-macho2img
|
||||
|
||||
AM_CFLAGS = $(TARGET_CFLAGS)
|
||||
AM_LDFLAGS = $(TARGET_LDFLAGS)
|
||||
AM_CPPFLAGS = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT)
|
||||
AM_CCASFLAGS = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT)
|
||||
|
||||
CFLAGS_PROGRAM += $(CFLAGS_PLATFORM)
|
||||
LDFLAGS_PROGRAM += $(LDFLAGS_PLATFORM)
|
||||
CPPFLAGS_PROGRAM += $(CPPFLAGS_PLATFORM)
|
||||
CCASFLAGS_PROGRAM += $(CCASFLAGS_PLATFORM)
|
||||
|
||||
CFLAGS_LIBRARY += $(CFLAGS_PLATFORM) -fno-builtin
|
||||
CPPFLAGS_LIBRARY += $(CPPFLAGS_PLATFORM)
|
||||
CCASFLAGS_LIBRARY += $(CCASFLAGS_PLATFORM)
|
||||
|
||||
build-VasEBoot-pep2elf$(BUILD_EXEEXT): $(top_srcdir)/util/VasEBoot-pe2elf.c $(top_srcdir)/VasEBoot-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DVAS_EBOOT_BUILD=1 -DVAS_EBOOT_TARGET_WORDSIZE=64 -DVAS_EBOOT_UTIL=1 -DVAS_EBOOT_BUILD_PROGRAM_NAME=\"build-VasEBoot-pep2elf\" $^
|
||||
CLEANFILES += build-VasEBoot-pep2elf$(BUILD_EXEEXT)
|
||||
|
||||
build-VasEBoot-pe2elf$(BUILD_EXEEXT): $(top_srcdir)/util/VasEBoot-pe2elf.c $(top_srcdir)/VasEBoot-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DVAS_EBOOT_BUILD=1 -DVAS_EBOOT_TARGET_WORDSIZE=32 -DVAS_EBOOT_UTIL=1 -DVAS_EBOOT_BUILD_PROGRAM_NAME=\"build-VasEBoot-pe2elf\" $^
|
||||
CLEANFILES += build-VasEBoot-pe2elf$(BUILD_EXEEXT)
|
||||
|
||||
# gentrigtables
|
||||
gentrigtables$(BUILD_EXEEXT): gentrigtables.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $< $(BUILD_LIBM)
|
||||
CLEANFILES += gentrigtables$(BUILD_EXEEXT)
|
||||
|
||||
build-VasEBoot-module-verifier$(BUILD_EXEEXT): $(top_srcdir)/util/VasEBoot-module-verifier.c $(top_srcdir)/util/VasEBoot-module-verifier32.c $(top_srcdir)/util/VasEBoot-module-verifier64.c $(top_srcdir)/VasEBoot-core/kern/emu/misc.c $(top_srcdir)/util/misc.c
|
||||
$(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DVAS_EBOOT_BUILD=1 -DVAS_EBOOT_UTIL=1 -DVAS_EBOOT_BUILD_PROGRAM_NAME=\"build-VasEBoot-module-verifier\" $^
|
||||
CLEANFILES += build-VasEBoot-module-verifier$(BUILD_EXEEXT)
|
||||
|
||||
# trigtables.c
|
||||
trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac
|
||||
./gentrigtables$(BUILD_EXEEXT) > $@
|
||||
CLEANFILES += trigtables.c
|
||||
|
||||
# XXX Use Automake's LEX & YACC support
|
||||
VasEBoot_script.tab.h: script/parser.y
|
||||
$(YACC) -d -p VasEBoot_script_yy -b VasEBoot_script $<
|
||||
VasEBoot_script.tab.c: VasEBoot_script.tab.h
|
||||
CLEANFILES += VasEBoot_script.tab.c VasEBoot_script.tab.h
|
||||
|
||||
# For the lexer.
|
||||
VasEBoot_script.yy.h: script/yylex.l
|
||||
$(LEX) -o VasEBoot_script.yy.c --header-file=VasEBoot_script.yy.h $<
|
||||
VasEBoot_script.yy.c: VasEBoot_script.yy.h
|
||||
|
||||
rs_decoder.h: $(srcdir)/lib/reed_solomon.c
|
||||
$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 -ffreestanding
|
||||
|
||||
CLEANFILES += VasEBoot_script.yy.c VasEBoot_script.yy.h
|
||||
|
||||
include $(srcdir)/Makefile.core.am
|
||||
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/cache.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/command.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/device.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/dl.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/sb.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/env.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/env_private.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/err.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/file.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/fs.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i18n.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/list.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lockdown.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/misc.h
|
||||
if COND_emu
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/compiler-rt-emu.h
|
||||
else
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/compiler-rt.h
|
||||
endif
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/mm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/parser.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/partition.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/key_protector.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/stack_protector.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/term.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/time.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/verify.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/mm_private.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/net.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/memory.h
|
||||
|
||||
if COND_i386_pc
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/pxe.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/int.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/tsc.h
|
||||
endif
|
||||
|
||||
if COND_i386_xen_pvh
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/int.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/loader.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/xen.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/xen/hypercall.h
|
||||
endif
|
||||
|
||||
if COND_i386_efi
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/pmtimer.h
|
||||
endif
|
||||
|
||||
if COND_i386_coreboot
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/coreboot/lbio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/video.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/video_fb.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/gfxterm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/font.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/bufio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
endif
|
||||
|
||||
if COND_i386_multiboot
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
endif
|
||||
|
||||
if COND_i386_qemu
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/tsc.h
|
||||
endif
|
||||
|
||||
if COND_i386_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/ieee1275/alloc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/tsc.h
|
||||
endif
|
||||
|
||||
if COND_i386_xen
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/xen.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/xen/hypercall.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/loader.h
|
||||
endif
|
||||
|
||||
if COND_x86_64_xen
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/xen.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/x86_64/xen/hypercall.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/loader.h
|
||||
endif
|
||||
|
||||
if COND_x86_64_efi
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/tsc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/i386/pmtimer.h
|
||||
endif
|
||||
|
||||
if COND_ia64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
endif
|
||||
|
||||
if COND_mips
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/cpu/kernel.h
|
||||
endif
|
||||
|
||||
if COND_mips_arc
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/arc/arc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
endif
|
||||
|
||||
if COND_mips_qemu_mips
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/keyboard_layouts.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/serial.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/loader.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
endif
|
||||
|
||||
if COND_mips_loongson
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/keyboard_layouts.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/time.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/video.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/video_fb.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/gfxterm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/font.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/bufio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/cs5536.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/serial.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/loader.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
endif
|
||||
|
||||
if COND_mips_qemu_mips
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/memory.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/machine/kernel.h
|
||||
endif
|
||||
|
||||
if COND_powerpc_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/ieee1275/alloc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/powerpc/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/powerpc/ieee1275/platform_keystore.h
|
||||
endif
|
||||
|
||||
if COND_sparc64_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/sparc64/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
endif
|
||||
|
||||
if COND_arm_uboot
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/uboot/uboot.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/uboot/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/lib/arg.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/arm/system.h
|
||||
endif
|
||||
|
||||
if COND_arm_coreboot
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/VasEBoot/keyboard_layouts.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/arm/system.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/video.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/video_fb.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/gfxterm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/font.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/bufio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/fdt.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/dma.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/arm/coreboot/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/fdtbus.h
|
||||
endif
|
||||
|
||||
if COND_arm_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/arm/system.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
endif
|
||||
|
||||
if COND_arm64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
endif
|
||||
|
||||
if COND_loongarch64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
endif
|
||||
|
||||
if COND_riscv32_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
endif
|
||||
|
||||
if COND_riscv64_efi
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/efi.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/efi/disk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/acpi.h
|
||||
endif
|
||||
|
||||
if COND_emu
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/datetime.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/emu/misc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/emu/net.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/emu/hostdisk.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/emu/hostfile.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/extcmd.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/emu/exec.h
|
||||
if COND_VAS_EBOOT_EMU_SDL
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/sdl.h
|
||||
endif
|
||||
if COND_VAS_EBOOT_EMU_SDL2
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/sdl.h
|
||||
endif
|
||||
if COND_VAS_EBOOT_EMU_PCI
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/VasEBoot/libpciaccess.h
|
||||
endif
|
||||
endif
|
||||
|
||||
symlist.h: $(top_builddir)/config.h $(KERNEL_HEADER_FILES)
|
||||
@list='$^'; \
|
||||
for p in $$list; do \
|
||||
echo "#include <$$p>" >> $@ || (rm -f $@; exit 1); \
|
||||
done
|
||||
CLEANFILES += symlist.h
|
||||
BUILT_SOURCES += symlist.h
|
||||
|
||||
symlist.c: symlist.h gensymlist.sh
|
||||
$(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DVAS_EBOOT_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1)
|
||||
cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1)
|
||||
rm -f symlist.p
|
||||
CLEANFILES += symlist.c
|
||||
BUILT_SOURCES += symlist.c
|
||||
|
||||
if COND_HAVE_ASM_USCORE
|
||||
ASM_PREFIX=_
|
||||
else
|
||||
ASM_PREFIX=
|
||||
endif
|
||||
|
||||
noinst_DATA += kernel_syms.lst
|
||||
|
||||
kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h
|
||||
$(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DVAS_EBOOT_SYMBOL_GENERATOR=1 $^ >kernel_syms.input
|
||||
cat kernel_syms.input | grep -v '^#' | sed -n \
|
||||
-e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \
|
||||
-e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \
|
||||
| sort -u >$@
|
||||
rm -f kernel_syms.input
|
||||
CLEANFILES += kernel_syms.lst
|
||||
|
||||
if COND_emu
|
||||
kern/emu/VasEBoot_emu-main.$(OBJEXT):VasEBoot_emu_init.h
|
||||
VasEBoot_emu-VasEBoot_emu_init.$(OBJEXT):VasEBoot_emu_init.h
|
||||
kern/emu/VasEBoot_emu_dyn-main.$(OBJEXT):VasEBoot_emu_init.h
|
||||
VasEBoot_emu_dyn-VasEBoot_emu_init.$(OBJEXT):VasEBoot_emu_init.h
|
||||
|
||||
VasEBoot_emu_init.h: genemuinitheader.sh $(MODULE_FILES)
|
||||
rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinitheader.sh $(TARGET_NM) > $@
|
||||
CLEANFILES += VasEBoot_emu_init.h
|
||||
|
||||
VasEBoot_emu_init.c: VasEBoot_emu_init.h genemuinit.sh $(MODULE_FILES)
|
||||
rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinit.sh $(TARGET_NM) > $@
|
||||
CLEANFILES += VasEBoot_emu_init.c
|
||||
endif
|
||||
|
||||
# List files
|
||||
|
||||
fs.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += fs.lst
|
||||
CLEANFILES += fs.lst
|
||||
|
||||
command.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
|
||||
-e "/EXTCOMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
|
||||
-e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
|
||||
-e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \
|
||||
-e "/COMMAND_LOCKDOWN_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += command.lst
|
||||
CLEANFILES += command.lst
|
||||
|
||||
partmap.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'PARTMAP_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += partmap.lst
|
||||
CLEANFILES += partmap.lst
|
||||
|
||||
terminal.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/INPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
|
||||
-e "/OUTPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += terminal.lst
|
||||
CLEANFILES += terminal.lst
|
||||
|
||||
fdt.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
|
||||
-e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += fdt.lst
|
||||
CLEANFILES += fdt.lst
|
||||
|
||||
parttool.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/PARTTOOL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += parttool.lst
|
||||
CLEANFILES += parttool.lst
|
||||
|
||||
video.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'VIDEO_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += video.lst
|
||||
CLEANFILES += video.lst
|
||||
|
||||
# but, crypto.lst is simply copied
|
||||
crypto.lst: $(srcdir)/lib/libgcrypt-VasEBoot/cipher/crypto.lst
|
||||
cp $^ $@
|
||||
platform_DATA += crypto.lst
|
||||
CLEANFILES += crypto.lst
|
||||
|
||||
extra_deps.lst:
|
||||
@echo $(EXTRA_DEPS) | sed "s/\s*:\s*/\n/g" > $@
|
||||
|
||||
syminfo.lst: gensyminfo.sh kernel_syms.lst extra_deps.lst $(MODULE_FILES)
|
||||
cat kernel_syms.lst extra_deps.lst > $@.new
|
||||
for m in $(MODULE_FILES); do \
|
||||
sh $< $$m >> $@.new || exit 1; \
|
||||
done
|
||||
mv $@.new $@
|
||||
|
||||
# generate global module dependencies list
|
||||
moddep.lst: syminfo.lst genmoddep.awk video.lst
|
||||
cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1)
|
||||
platform_DATA += moddep.lst
|
||||
CLEANFILES += config.log syminfo.lst moddep.lst extra_deps.lst
|
||||
|
||||
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-VasEBoot-module-verifier$(BUILD_EXEEXT)
|
||||
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
|
||||
platform_DATA += $(MOD_FILES)
|
||||
platform_DATA += modinfo.sh
|
||||
CLEANFILES += $(MOD_FILES)
|
||||
|
||||
if COND_ENABLE_EFIEMU
|
||||
efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
|
||||
-rm -f $@
|
||||
-rm -f $@.bin
|
||||
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -static -O2 -c -o $@.bin $<
|
||||
if test "x$(TARGET_APPLE_LINKER)" = x1; then \
|
||||
$(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \
|
||||
rm -f $@.bin ; \
|
||||
elif test ! -z "$(TARGET_OBJ2ELF)"; then \
|
||||
$(TARGET_OBJ2ELF) $@.bin || (rm -f $@.bin; exit 1); \
|
||||
mv $@.bin $@ ; \
|
||||
else \
|
||||
mv $@.bin $@ ; \
|
||||
fi
|
||||
|
||||
# Link format -arch,x86_64 means Apple linker
|
||||
efiemu64_c.o: efiemu/runtime/efiemu.c
|
||||
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $<
|
||||
|
||||
efiemu64_s.o: efiemu/runtime/efiemu.S
|
||||
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $<
|
||||
|
||||
efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
|
||||
-rm -f $@
|
||||
-rm -f $@.bin
|
||||
$(TARGET_CC) -m64 $(EFIEMU64_LINK_FORMAT) -nostdlib -static -Wl,-r -o $@.bin $^
|
||||
if test "x$(EFIEMU64_LINK_FORMAT)" = x-arch,x86_64; then \
|
||||
$(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \
|
||||
rm -f $@.bin; \
|
||||
else \
|
||||
mv $@.bin $@ ; \
|
||||
fi
|
||||
|
||||
platform_DATA += efiemu32.o efiemu64.o
|
||||
CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o
|
||||
endif
|
||||
|
||||
windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows
|
||||
windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA)
|
||||
test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform)
|
||||
for x in $(platform_DATA); do \
|
||||
cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \
|
||||
done
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/decompressor.h>
|
||||
|
||||
void *
|
||||
VasEBoot_memset (void *s, int c, VasEBoot_size_t len)
|
||||
{
|
||||
VasEBoot_uint8_t *ptr;
|
||||
for (ptr = s; len; ptr++, len--)
|
||||
*ptr = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *
|
||||
VasEBoot_memmove (void *dest, const void *src, VasEBoot_size_t n)
|
||||
{
|
||||
char *d = (char *) dest;
|
||||
const char *s = (const char *) src;
|
||||
|
||||
if (d < s)
|
||||
while (n--)
|
||||
*d++ = *s++;
|
||||
else
|
||||
{
|
||||
d += n;
|
||||
s += n;
|
||||
|
||||
while (n--)
|
||||
*--d = *--s;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *
|
||||
VasEBoot_memcpy (void *dest, const void *src, VasEBoot_size_t n)
|
||||
{
|
||||
return VasEBoot_memmove (dest, src, n);
|
||||
}
|
||||
|
||||
int
|
||||
VasEBoot_memcmp (const void *s1, const void *s2, VasEBoot_size_t n)
|
||||
{
|
||||
const unsigned char *t1 = s1;
|
||||
const unsigned char *t2 = s2;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if (*t1 != *t2)
|
||||
return (int) *t1 - (int) *t2;
|
||||
|
||||
t1++;
|
||||
t2++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *VasEBoot_decompressor_scratch;
|
||||
|
||||
void
|
||||
find_scratch (void *src, void *dst, unsigned long srcsize,
|
||||
unsigned long dstsize)
|
||||
{
|
||||
#ifdef _mips
|
||||
/* Decoding from ROM. */
|
||||
if (((VasEBoot_addr_t) src & 0x10000000))
|
||||
{
|
||||
VasEBoot_decompressor_scratch = (void *) ALIGN_UP((VasEBoot_addr_t) dst + dstsize,
|
||||
256);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((char *) src + srcsize > (char *) dst + dstsize)
|
||||
VasEBoot_decompressor_scratch = (void *) ALIGN_UP ((VasEBoot_addr_t) src + srcsize,
|
||||
256);
|
||||
else
|
||||
VasEBoot_decompressor_scratch = (void *) ALIGN_UP ((VasEBoot_addr_t) dst + dstsize,
|
||||
256);
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/decompressor.h>
|
||||
|
||||
void
|
||||
VasEBoot_decompress_core (void *src, void *dest, unsigned long n,
|
||||
unsigned long dstsize __attribute__ ((unused)))
|
||||
{
|
||||
char *d = (char *) dest;
|
||||
const char *s = (const char *) src;
|
||||
|
||||
if (d == s)
|
||||
return;
|
||||
|
||||
if (d < s)
|
||||
while (n--)
|
||||
*d++ = *s++;
|
||||
else
|
||||
{
|
||||
d += n;
|
||||
s += n;
|
||||
|
||||
while (n--)
|
||||
*--d = *--s;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/decompressor.h>
|
||||
|
||||
#include "xz.h"
|
||||
#include "xz_stream.h"
|
||||
|
||||
void
|
||||
VasEBoot_decompress_core (void *src, void *dst, unsigned long srcsize,
|
||||
unsigned long dstsize)
|
||||
{
|
||||
struct xz_dec *dec;
|
||||
struct xz_buf buf;
|
||||
|
||||
find_scratch (src, dst, srcsize, dstsize);
|
||||
|
||||
dec = xz_dec_init (VAS_EBOOT_DECOMPRESSOR_DICT_SIZE);
|
||||
|
||||
buf.in = src;
|
||||
buf.in_pos = 0;
|
||||
buf.in_size = srcsize;
|
||||
buf.out = dst;
|
||||
buf.out_pos = 0;
|
||||
buf.out_size = dstsize;
|
||||
|
||||
while (buf.in_pos != buf.in_size)
|
||||
{
|
||||
enum xz_ret xzret;
|
||||
xzret = xz_dec_run (dec, &buf);
|
||||
switch (xzret)
|
||||
{
|
||||
case XZ_MEMLIMIT_ERROR:
|
||||
case XZ_FORMAT_ERROR:
|
||||
case XZ_OPTIONS_ERROR:
|
||||
case XZ_DATA_ERROR:
|
||||
case XZ_BUF_ERROR:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,542 @@
|
|||
/* -*-Asm-*- */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/symbol.h>
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
|
||||
/*
|
||||
* defines for the code go here
|
||||
*/
|
||||
|
||||
/* Print message string */
|
||||
#define MSG(x) movw $x, %si; call LOCAL(message)
|
||||
#define ERR(x) movw $x, %si; jmp LOCAL(error_message)
|
||||
|
||||
.macro floppy
|
||||
part_start:
|
||||
|
||||
LOCAL(probe_values):
|
||||
.byte 36, 18, 15, 9, 0
|
||||
|
||||
LOCAL(floppy_probe):
|
||||
pushw %dx
|
||||
/*
|
||||
* Perform floppy probe.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
LOCAL(probe_values_minus_one) = LOCAL(probe_values) - 1
|
||||
movw MACRO_DOLLAR(LOCAL(probe_values_minus_one)), %si
|
||||
#else
|
||||
movw MACRO_DOLLAR(LOCAL(probe_values)) - 1, %si
|
||||
#endif
|
||||
|
||||
LOCAL(probe_loop):
|
||||
/* reset floppy controller INT 13h AH=0 */
|
||||
xorw %ax, %ax
|
||||
int MACRO_DOLLAR(0x13)
|
||||
|
||||
incw %si
|
||||
movb (%si), %cl
|
||||
|
||||
/* if number of sectors is 0, display error and die */
|
||||
testb %cl, %cl
|
||||
jnz 1f
|
||||
|
||||
/*
|
||||
* Floppy disk probe failure.
|
||||
*/
|
||||
MSG(fd_probe_error_string)
|
||||
jmp LOCAL(general_error)
|
||||
|
||||
/* "Floppy" */
|
||||
fd_probe_error_string: .asciz "Floppy"
|
||||
|
||||
1:
|
||||
/* perform read */
|
||||
movw MACRO_DOLLAR(VAS_EBOOT_BOOT_MACHINE_BUFFER_SEG), %bx
|
||||
movw %bx, %es
|
||||
xorw %bx, %bx
|
||||
movw MACRO_DOLLAR(0x201), %ax
|
||||
movb MACRO_DOLLAR(0), %ch
|
||||
movb MACRO_DOLLAR(0), %dh
|
||||
int MACRO_DOLLAR(0x13)
|
||||
|
||||
/* if error, jump to "LOCAL(probe_loop)" */
|
||||
jc LOCAL(probe_loop)
|
||||
|
||||
/* %cl is already the correct value! */
|
||||
movb MACRO_DOLLAR(1), %dh
|
||||
movb MACRO_DOLLAR(79), %ch
|
||||
|
||||
jmp LOCAL(final_init)
|
||||
.endm
|
||||
|
||||
.macro scratch
|
||||
|
||||
/* scratch space */
|
||||
mode:
|
||||
.byte 0
|
||||
disk_address_packet:
|
||||
sectors:
|
||||
.long 0
|
||||
heads:
|
||||
.long 0
|
||||
cylinders:
|
||||
.word 0
|
||||
sector_start:
|
||||
.byte 0
|
||||
head_start:
|
||||
.byte 0
|
||||
cylinder_start:
|
||||
.word 0
|
||||
/* more space... */
|
||||
.endm
|
||||
|
||||
.file "boot.S"
|
||||
|
||||
.text
|
||||
|
||||
/* Tell GAS to generate 16-bit instructions so that this code works
|
||||
in real mode. */
|
||||
.code16
|
||||
|
||||
.globl _start, start;
|
||||
_start:
|
||||
start:
|
||||
/*
|
||||
* _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00
|
||||
*/
|
||||
|
||||
/*
|
||||
* Beginning of the sector is compatible with the FAT/HPFS BIOS
|
||||
* parameter block.
|
||||
*/
|
||||
|
||||
jmp LOCAL(after_BPB)
|
||||
nop /* do I care about this ??? */
|
||||
|
||||
#ifdef HYBRID_BOOT
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
nop
|
||||
nop
|
||||
jmp LOCAL(after_BPB)
|
||||
#else
|
||||
/*
|
||||
* This space is for the BIOS parameter block!!!! Don't change
|
||||
* the first jump, nor start the code anywhere but right after
|
||||
* this area.
|
||||
*/
|
||||
|
||||
.org VAS_EBOOT_BOOT_MACHINE_BPB_START
|
||||
.org 4
|
||||
#endif
|
||||
#ifdef HYBRID_BOOT
|
||||
floppy
|
||||
#else
|
||||
scratch
|
||||
#endif
|
||||
|
||||
.org VAS_EBOOT_BOOT_MACHINE_BPB_END
|
||||
/*
|
||||
* End of BIOS parameter block.
|
||||
*/
|
||||
|
||||
LOCAL(kernel_address):
|
||||
.word VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR
|
||||
|
||||
#ifndef HYBRID_BOOT
|
||||
.org VAS_EBOOT_BOOT_MACHINE_KERNEL_SECTOR
|
||||
LOCAL(kernel_sector):
|
||||
.long 1
|
||||
LOCAL(kernel_sector_high):
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
.org VAS_EBOOT_BOOT_MACHINE_BOOT_DRIVE
|
||||
boot_drive:
|
||||
.byte 0xff /* the disk to load kernel from */
|
||||
/* 0xff means use the boot drive */
|
||||
|
||||
LOCAL(after_BPB):
|
||||
|
||||
/* general setup */
|
||||
cli /* we're not safe here! */
|
||||
|
||||
/*
|
||||
* This is a workaround for buggy BIOSes which don't pass boot
|
||||
* drive correctly. If VAS_EBOOT is installed into a HDD, check if
|
||||
* DL is masked correctly. If not, assume that the BIOS passed
|
||||
* a bogus value and set DL to 0x80, since this is the only
|
||||
* possible boot drive. If VAS_EBOOT is installed into a floppy,
|
||||
* this does nothing (only jump).
|
||||
*/
|
||||
.org VAS_EBOOT_BOOT_MACHINE_DRIVE_CHECK
|
||||
boot_drive_check:
|
||||
jmp 3f /* VasEBoot-setup may overwrite this jump */
|
||||
testb $0x80, %dl
|
||||
jz 2f
|
||||
3:
|
||||
/* Ignore %dl different from 0-0x0f and 0x80-0x8f. */
|
||||
testb $0x70, %dl
|
||||
jz 1f
|
||||
2:
|
||||
movb $0x80, %dl
|
||||
1:
|
||||
/*
|
||||
* ljmp to the next instruction because some bogus BIOSes
|
||||
* jump to 07C0:0000 instead of 0000:7C00.
|
||||
*/
|
||||
ljmp $0, $real_start
|
||||
|
||||
real_start:
|
||||
|
||||
/* set up %ds and %ss as offset from 0 */
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %ss
|
||||
|
||||
/* set up the REAL stack */
|
||||
movw $VAS_EBOOT_BOOT_MACHINE_STACK_SEG, %sp
|
||||
|
||||
sti /* we're safe again */
|
||||
|
||||
/*
|
||||
* Check if we have a forced disk reference here
|
||||
*/
|
||||
movb boot_drive, %al
|
||||
cmpb $0xff, %al
|
||||
je 1f
|
||||
movb %al, %dl
|
||||
1:
|
||||
/* save drive reference first thing! */
|
||||
pushw %dx
|
||||
|
||||
/* print a notification message on the screen */
|
||||
MSG(notification_string)
|
||||
|
||||
/* set %si to the disk address packet */
|
||||
movw $disk_address_packet, %si
|
||||
|
||||
/* check if LBA is supported */
|
||||
movb $0x41, %ah
|
||||
movw $0x55aa, %bx
|
||||
int $0x13
|
||||
|
||||
/*
|
||||
* %dl may have been clobbered by INT 13, AH=41H.
|
||||
* This happens, for example, with AST BIOS 1.04.
|
||||
*/
|
||||
popw %dx
|
||||
pushw %dx
|
||||
|
||||
/* use CHS if fails */
|
||||
jc LOCAL(chs_mode)
|
||||
cmpw $0xaa55, %bx
|
||||
jne LOCAL(chs_mode)
|
||||
|
||||
andw $1, %cx
|
||||
jz LOCAL(chs_mode)
|
||||
|
||||
LOCAL(lba_mode):
|
||||
xorw %ax, %ax
|
||||
movw %ax, 4(%si)
|
||||
|
||||
incw %ax
|
||||
/* set the mode to non-zero */
|
||||
movb %al, -1(%si)
|
||||
|
||||
/* the blocks */
|
||||
movw %ax, 2(%si)
|
||||
|
||||
/* the size and the reserved byte */
|
||||
movw $0x0010, (%si)
|
||||
|
||||
/* the absolute address */
|
||||
movl LOCAL(kernel_sector), %ebx
|
||||
movl %ebx, 8(%si)
|
||||
movl LOCAL(kernel_sector_high), %ebx
|
||||
movl %ebx, 12(%si)
|
||||
|
||||
/* the segment of buffer address */
|
||||
movw $VAS_EBOOT_BOOT_MACHINE_BUFFER_SEG, 6(%si)
|
||||
|
||||
/*
|
||||
* BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
|
||||
* Call with %ah = 0x42
|
||||
* %dl = drive number
|
||||
* %ds:%si = segment:offset of disk address packet
|
||||
* Return:
|
||||
* %al = 0x0 on success; err code on failure
|
||||
*/
|
||||
|
||||
movb $0x42, %ah
|
||||
int $0x13
|
||||
|
||||
/* LBA read is not supported, so fallback to CHS. */
|
||||
jc LOCAL(chs_mode)
|
||||
|
||||
movw $VAS_EBOOT_BOOT_MACHINE_BUFFER_SEG, %bx
|
||||
jmp LOCAL(copy_buffer)
|
||||
|
||||
LOCAL(chs_mode):
|
||||
/*
|
||||
* Determine the hard disk geometry from the BIOS!
|
||||
* We do this first, so that LS-120 IDE floppies work correctly.
|
||||
*/
|
||||
movb $8, %ah
|
||||
int $0x13
|
||||
jnc LOCAL(final_init)
|
||||
|
||||
popw %dx
|
||||
/*
|
||||
* The call failed, so maybe use the floppy probe instead.
|
||||
*/
|
||||
testb %dl, %dl
|
||||
jnb LOCAL(floppy_probe)
|
||||
|
||||
/* Nope, we definitely have a hard disk, and we're screwed. */
|
||||
ERR(hd_probe_error_string)
|
||||
|
||||
LOCAL(final_init):
|
||||
/* set the mode to zero */
|
||||
movzbl %dh, %eax
|
||||
movb %ah, -1(%si)
|
||||
|
||||
/* save number of heads */
|
||||
incw %ax
|
||||
movl %eax, 4(%si)
|
||||
|
||||
movzbw %cl, %dx
|
||||
shlw $2, %dx
|
||||
movb %ch, %al
|
||||
movb %dh, %ah
|
||||
|
||||
/* save number of cylinders */
|
||||
incw %ax
|
||||
movw %ax, 8(%si)
|
||||
|
||||
movzbw %dl, %ax
|
||||
shrb $2, %al
|
||||
|
||||
/* save number of sectors */
|
||||
movl %eax, (%si)
|
||||
|
||||
setup_sectors:
|
||||
/* load logical sector start (top half) */
|
||||
movl LOCAL(kernel_sector_high), %eax
|
||||
|
||||
orl %eax, %eax
|
||||
jnz LOCAL(geometry_error)
|
||||
|
||||
/* load logical sector start (bottom half) */
|
||||
movl LOCAL(kernel_sector), %eax
|
||||
|
||||
/* zero %edx */
|
||||
xorl %edx, %edx
|
||||
|
||||
/* divide by number of sectors */
|
||||
divl (%si)
|
||||
|
||||
/* save sector start */
|
||||
movb %dl, %cl
|
||||
|
||||
xorw %dx, %dx /* zero %edx */
|
||||
divl 4(%si) /* divide by number of heads */
|
||||
|
||||
/* do we need too many cylinders? */
|
||||
cmpw 8(%si), %ax
|
||||
jge LOCAL(geometry_error)
|
||||
|
||||
/* normalize sector start (1-based) */
|
||||
incb %cl
|
||||
|
||||
/* low bits of cylinder start */
|
||||
movb %al, %ch
|
||||
|
||||
/* high bits of cylinder start */
|
||||
xorb %al, %al
|
||||
shrw $2, %ax
|
||||
orb %al, %cl
|
||||
|
||||
/* save head start */
|
||||
movb %dl, %al
|
||||
|
||||
/* restore %dl */
|
||||
popw %dx
|
||||
|
||||
/* head start */
|
||||
movb %al, %dh
|
||||
|
||||
/*
|
||||
* BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
|
||||
* Call with %ah = 0x2
|
||||
* %al = number of sectors
|
||||
* %ch = cylinder
|
||||
* %cl = sector (bits 6-7 are high bits of "cylinder")
|
||||
* %dh = head
|
||||
* %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
|
||||
* %es:%bx = segment:offset of buffer
|
||||
* Return:
|
||||
* %al = 0x0 on success; err code on failure
|
||||
*/
|
||||
|
||||
movw $VAS_EBOOT_BOOT_MACHINE_BUFFER_SEG, %bx
|
||||
movw %bx, %es /* load %es segment with disk buffer */
|
||||
|
||||
xorw %bx, %bx /* %bx = 0, put it at 0 in the segment */
|
||||
movw $0x0201, %ax /* function 2 */
|
||||
int $0x13
|
||||
|
||||
jc LOCAL(read_error)
|
||||
|
||||
movw %es, %bx
|
||||
|
||||
LOCAL(copy_buffer):
|
||||
/*
|
||||
* We need to save %cx and %si because the startup code in
|
||||
* kernel uses them without initializing them.
|
||||
*/
|
||||
pusha
|
||||
pushw %ds
|
||||
|
||||
movw $0x100, %cx
|
||||
movw %bx, %ds
|
||||
xorw %si, %si
|
||||
movw $VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR, %di
|
||||
movw %si, %es
|
||||
|
||||
cld
|
||||
|
||||
rep
|
||||
movsw
|
||||
|
||||
popw %ds
|
||||
popa
|
||||
|
||||
/* boot kernel */
|
||||
jmp *(LOCAL(kernel_address))
|
||||
|
||||
/* END OF MAIN LOOP */
|
||||
|
||||
/*
|
||||
* BIOS Geometry translation error (past the end of the disk geometry!).
|
||||
*/
|
||||
LOCAL(geometry_error):
|
||||
ERR(geometry_error_string)
|
||||
|
||||
/*
|
||||
* Read error on the disk.
|
||||
*/
|
||||
LOCAL(read_error):
|
||||
movw $read_error_string, %si
|
||||
LOCAL(error_message):
|
||||
call LOCAL(message)
|
||||
LOCAL(general_error):
|
||||
MSG(general_error_string)
|
||||
|
||||
/* go here when you need to stop the machine hard after an error condition */
|
||||
/* tell the BIOS a boot failure, which may result in no effect */
|
||||
int $0x18
|
||||
LOCAL(stop):
|
||||
jmp LOCAL(stop)
|
||||
|
||||
notification_string: .asciz "VAS_EBOOT "
|
||||
geometry_error_string: .asciz "Geom"
|
||||
hd_probe_error_string: .asciz "Hard Disk"
|
||||
read_error_string: .asciz "Read"
|
||||
general_error_string: .asciz " Error\r\n"
|
||||
|
||||
/*
|
||||
* message: write the string pointed to by %si
|
||||
*
|
||||
* WARNING: trashes %si, %ax, and %bx
|
||||
*/
|
||||
|
||||
/*
|
||||
* Use BIOS "int 10H Function 0Eh" to write character in teletype mode
|
||||
* %ah = 0xe %al = character
|
||||
* %bh = page %bl = foreground color (graphics modes)
|
||||
*/
|
||||
1:
|
||||
movw $0x0001, %bx
|
||||
movb $0xe, %ah
|
||||
int $0x10 /* display a byte */
|
||||
LOCAL(message):
|
||||
lodsb
|
||||
cmpb $0, %al
|
||||
jne 1b /* if not end of string, jmp to display */
|
||||
ret
|
||||
|
||||
/*
|
||||
* Windows NT breaks compatibility by embedding a magic
|
||||
* number here.
|
||||
*/
|
||||
|
||||
#ifdef HYBRID_BOOT
|
||||
.org 0x1b0
|
||||
LOCAL(kernel_sector):
|
||||
.long 1
|
||||
LOCAL(kernel_sector_high):
|
||||
.long 0
|
||||
#endif
|
||||
.org VAS_EBOOT_BOOT_MACHINE_WINDOWS_NT_MAGIC
|
||||
nt_magic:
|
||||
.long 0
|
||||
.word 0
|
||||
|
||||
/*
|
||||
* This is where an MBR would go if on a hard disk. The code
|
||||
* here isn't even referenced unless we're on a floppy. Kinda
|
||||
* sneaky, huh?
|
||||
*/
|
||||
|
||||
.org VAS_EBOOT_BOOT_MACHINE_PART_START
|
||||
|
||||
#ifndef HYBRID_BOOT
|
||||
floppy
|
||||
#else
|
||||
scratch
|
||||
#endif
|
||||
|
||||
.org VAS_EBOOT_BOOT_MACHINE_PART_END
|
||||
|
||||
/* the last 2 bytes in the sector 0 contain the signature */
|
||||
.word VAS_EBOOT_BOOT_MACHINE_SIGNATURE
|
||||
|
|
@ -1,31 +1,31 @@
|
|||
/* -*-Asm-*- */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* VAS_EBOOT 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,
|
||||
* VAS_EBOOT 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/>.
|
||||
* along with VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/machine/boot.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
#include <VasEBoot/symbol.h>
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
#include <VasEBoot/machine/kernel.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
.file "cdboot.S"
|
||||
|
||||
#define CODE_ADDR 0x6000
|
||||
#define DATA_ADDR ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
|
||||
#define DATA_ADDR ((VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
|
||||
|
||||
#define CDSEC_SHIFT 11
|
||||
#define CDBLK_LENG 16
|
||||
|
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2006,2007,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/symbol.h>
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
|
||||
/*
|
||||
* defines for the code go here
|
||||
*/
|
||||
|
||||
#define MSG(x) movw $x, %si; call LOCAL(message)
|
||||
|
||||
.file "diskboot.S"
|
||||
|
||||
.text
|
||||
|
||||
/* Tell GAS to generate 16-bit instructions so that this code works
|
||||
in real mode. */
|
||||
.code16
|
||||
|
||||
.globl start, _start
|
||||
start:
|
||||
_start:
|
||||
/*
|
||||
* _start is loaded at 0x8000 and is jumped to with
|
||||
* CS:IP 0:0x8000 in kernel.
|
||||
*/
|
||||
|
||||
/*
|
||||
* we continue to use the stack for boot.img and assume that
|
||||
* some registers are set to correct values. See boot.S
|
||||
* for more information.
|
||||
*/
|
||||
|
||||
/* save drive reference first thing! */
|
||||
pushw %dx
|
||||
|
||||
/* print a notification message on the screen */
|
||||
pushw %si
|
||||
MSG(notification_string)
|
||||
popw %si
|
||||
|
||||
/* this sets up for the first run through "bootloop" */
|
||||
movw $LOCAL(firstlist), %di
|
||||
|
||||
/* save the sector number of the second sector in %ebp */
|
||||
movl (%di), %ebp
|
||||
|
||||
/* this is the loop for reading the rest of the kernel in */
|
||||
LOCAL(bootloop):
|
||||
|
||||
/* check the number of sectors to read */
|
||||
cmpw $0, 8(%di)
|
||||
|
||||
/* if zero, go to the start function */
|
||||
je LOCAL(bootit)
|
||||
|
||||
LOCAL(setup_sectors):
|
||||
/* check if we use LBA or CHS */
|
||||
cmpb $0, -1(%si)
|
||||
|
||||
/* use CHS if zero, LBA otherwise */
|
||||
je LOCAL(chs_mode)
|
||||
|
||||
/* load logical sector start */
|
||||
movl (%di), %ebx
|
||||
movl 4(%di), %ecx
|
||||
|
||||
/* the maximum is limited to 0x7f because of Phoenix EDD */
|
||||
xorl %eax, %eax
|
||||
movb $0x7f, %al
|
||||
|
||||
/* how many do we really want to read? */
|
||||
cmpw %ax, 8(%di) /* compare against total number of sectors */
|
||||
|
||||
/* which is greater? */
|
||||
jg 1f
|
||||
|
||||
/* if less than, set to total */
|
||||
movw 8(%di), %ax
|
||||
|
||||
1:
|
||||
/* subtract from total */
|
||||
subw %ax, 8(%di)
|
||||
|
||||
/* add into logical sector start */
|
||||
addl %eax, (%di)
|
||||
adcl $0, 4(%di)
|
||||
|
||||
/* set up disk address packet */
|
||||
|
||||
/* the size and the reserved byte */
|
||||
movw $0x0010, (%si)
|
||||
|
||||
/* the number of sectors */
|
||||
movw %ax, 2(%si)
|
||||
|
||||
/* the absolute address */
|
||||
movl %ebx, 8(%si)
|
||||
movl %ecx, 12(%si)
|
||||
|
||||
/* the segment of buffer address */
|
||||
movw $VAS_EBOOT_BOOT_MACHINE_BUFFER_SEG, 6(%si)
|
||||
|
||||
/* save %ax from destruction! */
|
||||
pushw %ax
|
||||
|
||||
/* the offset of buffer address */
|
||||
movw $0, 4(%si)
|
||||
|
||||
/*
|
||||
* BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
|
||||
* Call with %ah = 0x42
|
||||
* %dl = drive number
|
||||
* %ds:%si = segment:offset of disk address packet
|
||||
* Return:
|
||||
* %al = 0x0 on success; err code on failure
|
||||
*/
|
||||
|
||||
movb $0x42, %ah
|
||||
int $0x13
|
||||
|
||||
jc LOCAL(read_error)
|
||||
|
||||
movw $VAS_EBOOT_BOOT_MACHINE_BUFFER_SEG, %bx
|
||||
jmp LOCAL(copy_buffer)
|
||||
|
||||
LOCAL(chs_mode):
|
||||
/* load logical sector start (top half) */
|
||||
movl 4(%di), %eax
|
||||
orl %eax, %eax
|
||||
jnz LOCAL(geometry_error)
|
||||
|
||||
/* load logical sector start (bottom half) */
|
||||
movl (%di), %eax
|
||||
|
||||
/* zero %edx */
|
||||
xorl %edx, %edx
|
||||
|
||||
/* divide by number of sectors */
|
||||
divl (%si)
|
||||
|
||||
/* save sector start */
|
||||
movb %dl, 10(%si)
|
||||
|
||||
xorl %edx, %edx /* zero %edx */
|
||||
divl 4(%si) /* divide by number of heads */
|
||||
|
||||
/* save head start */
|
||||
movb %dl, 11(%si)
|
||||
|
||||
/* save cylinder start */
|
||||
movw %ax, 12(%si)
|
||||
|
||||
/* do we need too many cylinders? */
|
||||
cmpw 8(%si), %ax
|
||||
jge LOCAL(geometry_error)
|
||||
|
||||
/* determine the maximum sector length of this read */
|
||||
movw (%si), %ax /* get number of sectors per track/head */
|
||||
|
||||
/* subtract sector start */
|
||||
subb 10(%si), %al
|
||||
|
||||
/* how many do we really want to read? */
|
||||
cmpw %ax, 8(%di) /* compare against total number of sectors */
|
||||
|
||||
|
||||
/* which is greater? */
|
||||
jg 2f
|
||||
|
||||
/* if less than, set to total */
|
||||
movw 8(%di), %ax
|
||||
|
||||
2:
|
||||
/* subtract from total */
|
||||
subw %ax, 8(%di)
|
||||
|
||||
/* add into logical sector start */
|
||||
addl %eax, (%di)
|
||||
adcl $0, 4(%di)
|
||||
|
||||
/*
|
||||
* This is the loop for taking care of BIOS geometry translation (ugh!)
|
||||
*/
|
||||
|
||||
/* get high bits of cylinder */
|
||||
movb 13(%si), %dl
|
||||
|
||||
shlb $6, %dl /* shift left by 6 bits */
|
||||
movb 10(%si), %cl /* get sector */
|
||||
|
||||
incb %cl /* normalize sector (sectors go
|
||||
from 1-N, not 0-(N-1) ) */
|
||||
orb %dl, %cl /* composite together */
|
||||
movb 12(%si), %ch /* sector+hcyl in cl, cylinder in ch */
|
||||
|
||||
/* restore %dx */
|
||||
popw %dx
|
||||
pushw %dx
|
||||
|
||||
/* head number */
|
||||
movb 11(%si), %dh
|
||||
|
||||
pushw %ax /* save %ax from destruction! */
|
||||
|
||||
/*
|
||||
* BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
|
||||
* Call with %ah = 0x2
|
||||
* %al = number of sectors
|
||||
* %ch = cylinder
|
||||
* %cl = sector (bits 6-7 are high bits of "cylinder")
|
||||
* %dh = head
|
||||
* %dl = drive (0x80 for hard disk, 0x0 for floppy disk)
|
||||
* %es:%bx = segment:offset of buffer
|
||||
* Return:
|
||||
* %al = 0x0 on success; err code on failure
|
||||
*/
|
||||
|
||||
movw $VAS_EBOOT_BOOT_MACHINE_BUFFER_SEG, %bx
|
||||
movw %bx, %es /* load %es segment with disk buffer */
|
||||
|
||||
xorw %bx, %bx /* %bx = 0, put it at 0 in the segment */
|
||||
movb $0x2, %ah /* function 2 */
|
||||
int $0x13
|
||||
|
||||
jc LOCAL(read_error)
|
||||
|
||||
/* save source segment */
|
||||
movw %es, %bx
|
||||
|
||||
LOCAL(copy_buffer):
|
||||
|
||||
/* load addresses for copy from disk buffer to destination */
|
||||
movw 10(%di), %es /* load destination segment */
|
||||
|
||||
/* restore %ax */
|
||||
popw %ax
|
||||
|
||||
/* determine the next possible destination address (presuming
|
||||
512 byte sectors!) */
|
||||
shlw $5, %ax /* shift %ax five bits to the left */
|
||||
addw %ax, 10(%di) /* add the corrected value to the destination
|
||||
address for next time */
|
||||
|
||||
/* save addressing regs */
|
||||
pusha
|
||||
pushw %ds
|
||||
|
||||
/* get the copy length */
|
||||
shlw $3, %ax
|
||||
movw %ax, %cx
|
||||
|
||||
xorw %di, %di /* zero offset of destination addresses */
|
||||
xorw %si, %si /* zero offset of source addresses */
|
||||
movw %bx, %ds /* restore the source segment */
|
||||
|
||||
cld /* sets the copy direction to forward */
|
||||
|
||||
/* perform copy */
|
||||
rep /* sets a repeat */
|
||||
movsw /* this runs the actual copy */
|
||||
|
||||
/* restore addressing regs and print a dot with correct DS
|
||||
(MSG modifies SI, which is saved, and unused AX and BX) */
|
||||
popw %ds
|
||||
MSG(notification_step)
|
||||
popa
|
||||
|
||||
/* check if finished with this dataset */
|
||||
cmpw $0, 8(%di)
|
||||
jne LOCAL(setup_sectors)
|
||||
|
||||
/* update position to load from */
|
||||
subw $VAS_EBOOT_BOOT_MACHINE_LIST_SIZE, %di
|
||||
|
||||
/* jump to bootloop */
|
||||
jmp LOCAL(bootloop)
|
||||
|
||||
/* END OF MAIN LOOP */
|
||||
|
||||
LOCAL(bootit):
|
||||
/* print a newline */
|
||||
MSG(notification_done)
|
||||
popw %dx /* this makes sure %dl is our "boot" drive */
|
||||
ljmp $0, $(VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR + 0x200)
|
||||
|
||||
|
||||
/*
|
||||
* BIOS Geometry translation error (past the end of the disk geometry!).
|
||||
*/
|
||||
LOCAL(geometry_error):
|
||||
MSG(geometry_error_string)
|
||||
jmp LOCAL(general_error)
|
||||
|
||||
/*
|
||||
* Read error on the disk.
|
||||
*/
|
||||
LOCAL(read_error):
|
||||
MSG(read_error_string)
|
||||
|
||||
LOCAL(general_error):
|
||||
MSG(general_error_string)
|
||||
|
||||
/* go here when you need to stop the machine hard after an error condition */
|
||||
LOCAL(stop): jmp LOCAL(stop)
|
||||
|
||||
notification_string: .asciz "loading"
|
||||
|
||||
notification_step: .asciz "."
|
||||
notification_done: .asciz "\r\n"
|
||||
|
||||
geometry_error_string: .asciz "Geom"
|
||||
read_error_string: .asciz "Read"
|
||||
general_error_string: .asciz " Error"
|
||||
|
||||
/*
|
||||
* message: write the string pointed to by %si
|
||||
*
|
||||
* WARNING: trashes %si, %ax, and %bx
|
||||
*/
|
||||
|
||||
/*
|
||||
* Use BIOS "int 10H Function 0Eh" to write character in teletype mode
|
||||
* %ah = 0xe %al = character
|
||||
* %bh = page %bl = foreground color (graphics modes)
|
||||
*/
|
||||
1:
|
||||
movw $0x0001, %bx
|
||||
movb $0xe, %ah
|
||||
int $0x10 /* display a byte */
|
||||
|
||||
incw %si
|
||||
LOCAL(message):
|
||||
movb (%si), %al
|
||||
cmpb $0, %al
|
||||
jne 1b /* if not end of string, jmp to display */
|
||||
ret
|
||||
|
||||
/*
|
||||
* This area is an empty space between the main body of code below which
|
||||
* grows up (fixed after compilation, but between releases it may change
|
||||
* in size easily), and the lists of sectors to read, which grows down
|
||||
* from a fixed top location.
|
||||
*/
|
||||
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
.org 0x200 - VAS_EBOOT_BOOT_MACHINE_LIST_SIZE
|
||||
LOCAL(firstlist): /* this label has to be before the first list entry!!! */
|
||||
/* fill the first data listing with the default */
|
||||
blocklist_default_start:
|
||||
/* this is the sector start parameter, in logical sectors from
|
||||
the start of the disk, sector 0 */
|
||||
.long 2, 0
|
||||
blocklist_default_len:
|
||||
/* this is the number of sectors to read. VasEBoot-mkimage
|
||||
will fill this up */
|
||||
.word 0
|
||||
blocklist_default_seg:
|
||||
/* this is the segment of the starting address to load the data into */
|
||||
.word (VAS_EBOOT_BOOT_MACHINE_KERNEL_SEG + 0x20)
|
||||
|
|
@ -1,33 +1,33 @@
|
|||
/* -*-Asm-*- */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* VAS_EBOOT 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,
|
||||
* VAS_EBOOT 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/>.
|
||||
* along with VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/machine/boot.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
#include <VasEBoot/symbol.h>
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
#include <VasEBoot/machine/kernel.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
.file "lnxboot.S"
|
||||
|
||||
#define CODE_ADDR 0x6000
|
||||
#define CODE_SECTORS 1
|
||||
#define DATA_ADDR ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
|
||||
#define DATA_ADDR ((VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
|
||||
|
||||
#define BLCK_LENG 0x4000
|
||||
|
||||
|
|
@ -201,15 +201,15 @@ real_code_2:
|
|||
1:
|
||||
|
||||
movl $(DATA_ADDR + 0x1000), %edi
|
||||
movl %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx
|
||||
addl $GRUB_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE, %ecx
|
||||
movl %ss:(DATA_ADDR + VAS_EBOOT_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx
|
||||
addl $VAS_EBOOT_DECOMPRESSOR_I386_PC_MAX_DECOMPRESSOR_SIZE, %ecx
|
||||
|
||||
2:
|
||||
call LOCAL(move_memory)
|
||||
|
||||
movb %dh, %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE + 2)
|
||||
movb %dh, %ss:(DATA_ADDR + VAS_EBOOT_DECOMPRESSOR_I386_PC_BOOT_DEVICE + 2)
|
||||
movb (reg_edx + 2 - start), %dh
|
||||
movb %dh, %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_I386_PC_BOOT_DEVICE + 1)
|
||||
movb %dh, %ss:(DATA_ADDR + VAS_EBOOT_DECOMPRESSOR_I386_PC_BOOT_DEVICE + 1)
|
||||
|
||||
movb $0xFF, %dh
|
||||
|
||||
|
|
@ -1,19 +1,19 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* VAS_EBOOT 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,
|
||||
* VAS_EBOOT 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/>.
|
||||
* along with VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define FIXED_PROPS
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* VAS_EBOOT 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,
|
||||
* VAS_EBOOT 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/>.
|
||||
* along with VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/machine/boot.h>
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
|
||||
.file "pxeboot.S"
|
||||
.text
|
||||
|
|
@ -30,7 +30,7 @@ _start:
|
|||
start:
|
||||
|
||||
/* Use drive number 0x7F for PXE */
|
||||
movb $GRUB_BOOT_MACHINE_PXE_DL, %dl
|
||||
movb $VAS_EBOOT_BOOT_MACHINE_PXE_DL, %dl
|
||||
|
||||
/* Jump to the real world */
|
||||
ljmp $0, $0x8200
|
||||
|
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <VasEBoot/symbol.h>
|
||||
#include <VasEBoot/offsets.h>
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
#include <VasEBoot/machine/memory.h>
|
||||
#include <VasEBoot/machine/kernel.h>
|
||||
|
||||
#define ABS(x) ((x) - LOCAL (base) + VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR + 0x200)
|
||||
|
||||
.file "startup_raw.S"
|
||||
|
||||
.text
|
||||
|
||||
/* Tell GAS to generate 16-bit instructions so that this code works
|
||||
in real mode. */
|
||||
.code16
|
||||
|
||||
.globl start, _start
|
||||
start:
|
||||
_start:
|
||||
LOCAL (base):
|
||||
/*
|
||||
* Guarantee that "main" is loaded at 0x0:0x8200.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000)
|
||||
#else
|
||||
ljmp $0, $ABS(LOCAL (codestart))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is a special data area.
|
||||
*/
|
||||
|
||||
.org VAS_EBOOT_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
|
||||
LOCAL(compressed_size):
|
||||
.long 0
|
||||
.org VAS_EBOOT_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
|
||||
LOCAL(uncompressed_size):
|
||||
.long 0
|
||||
|
||||
.org VAS_EBOOT_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
|
||||
reed_solomon_redundancy:
|
||||
.long 0
|
||||
.org VAS_EBOOT_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH
|
||||
.short (LOCAL(reed_solomon_part) - _start)
|
||||
|
||||
/*
|
||||
* This is the area for all of the special variables.
|
||||
*/
|
||||
.org VAS_EBOOT_DECOMPRESSOR_I386_PC_BOOT_DEVICE
|
||||
LOCAL(boot_dev):
|
||||
.byte 0xFF, 0xFF, 0xFF
|
||||
LOCAL(boot_drive):
|
||||
.byte 0x00
|
||||
|
||||
/* the real mode code continues... */
|
||||
LOCAL (codestart):
|
||||
cli /* we're not safe here! */
|
||||
|
||||
/* set up %ds, %ss, and %es */
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %ss
|
||||
movw %ax, %es
|
||||
|
||||
/* set up the real mode/BIOS stack */
|
||||
movl $VAS_EBOOT_MEMORY_MACHINE_REAL_STACK, %ebp
|
||||
movl %ebp, %esp
|
||||
|
||||
sti /* we're safe again */
|
||||
|
||||
/* save the boot drive */
|
||||
movb %dl, LOCAL(boot_drive)
|
||||
|
||||
/* reset disk system (%ah = 0) */
|
||||
int $0x13
|
||||
|
||||
/* transition to protected mode */
|
||||
calll real_to_prot
|
||||
|
||||
/* The ".code32" directive takes GAS out of 16-bit mode. */
|
||||
.code32
|
||||
|
||||
cld
|
||||
call VasEBoot_gate_a20
|
||||
|
||||
movl LOCAL(compressed_size), %edx
|
||||
#ifdef __APPLE__
|
||||
addl $decompressor_end, %edx
|
||||
subl $(LOCAL(reed_solomon_part)), %edx
|
||||
#else
|
||||
addl $(LOCAL(decompressor_end) - LOCAL(reed_solomon_part)), %edx
|
||||
#endif
|
||||
movl reed_solomon_redundancy, %ecx
|
||||
leal LOCAL(reed_solomon_part), %eax
|
||||
cld
|
||||
call EXT_C (VasEBoot_reed_solomon_recover)
|
||||
jmp post_reed_solomon
|
||||
|
||||
#include "../../../kern/i386/realmode.S"
|
||||
|
||||
/*
|
||||
*
|
||||
* This is a workaround for clang adding a section containing only .addrsig
|
||||
* Since clang itself is unable to assemble this pseudo-opcode, just replace
|
||||
* it with .text
|
||||
*
|
||||
*/
|
||||
#define addrsig text
|
||||
#include <rs_decoder.h>
|
||||
#undef addrsig
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* VasEBoot_gate_a20(void)
|
||||
*
|
||||
* Gate address-line 20 for high memory.
|
||||
*
|
||||
* This routine is probably overconservative in what it does, but so what?
|
||||
*
|
||||
* It also eats any keystrokes in the keyboard buffer. :-(
|
||||
*/
|
||||
|
||||
VasEBoot_gate_a20:
|
||||
gate_a20_test_current_state:
|
||||
/* first of all, test if already in a good state */
|
||||
call gate_a20_check_state
|
||||
testb %al, %al
|
||||
jnz gate_a20_try_bios
|
||||
ret
|
||||
|
||||
gate_a20_try_bios:
|
||||
/* second, try a BIOS call */
|
||||
pushl %ebp
|
||||
call prot_to_real
|
||||
|
||||
.code16
|
||||
movw $0x2401, %ax
|
||||
int $0x15
|
||||
|
||||
calll real_to_prot
|
||||
.code32
|
||||
|
||||
popl %ebp
|
||||
call gate_a20_check_state
|
||||
testb %al, %al
|
||||
jnz gate_a20_try_system_control_port_a
|
||||
ret
|
||||
|
||||
gate_a20_try_system_control_port_a:
|
||||
/*
|
||||
* In macbook, the keyboard test would hang the machine, so we move
|
||||
* this forward.
|
||||
*/
|
||||
/* fourth, try the system control port A */
|
||||
inb $0x92
|
||||
andb $(~0x03), %al
|
||||
orb $0x02, %al
|
||||
outb $0x92
|
||||
|
||||
call gate_a20_check_state
|
||||
testb %al, %al
|
||||
jnz gate_a20_try_keyboard_controller
|
||||
ret
|
||||
|
||||
gate_a20_flush_keyboard_buffer:
|
||||
inb $0x64
|
||||
andb $0x02, %al
|
||||
jnz gate_a20_flush_keyboard_buffer
|
||||
2:
|
||||
inb $0x64
|
||||
andb $0x01, %al
|
||||
jz 3f
|
||||
inb $0x60
|
||||
jmp 2b
|
||||
3:
|
||||
ret
|
||||
|
||||
gate_a20_try_keyboard_controller:
|
||||
/* third, try the keyboard controller */
|
||||
call gate_a20_flush_keyboard_buffer
|
||||
|
||||
movb $0xd1, %al
|
||||
outb $0x64
|
||||
4:
|
||||
inb $0x64
|
||||
andb $0x02, %al
|
||||
jnz 4b
|
||||
|
||||
movb $0xdf, %al
|
||||
outb $0x60
|
||||
call gate_a20_flush_keyboard_buffer
|
||||
|
||||
/* output a dummy command (USB keyboard hack) */
|
||||
movb $0xff, %al
|
||||
outb $0x64
|
||||
call gate_a20_flush_keyboard_buffer
|
||||
|
||||
call gate_a20_check_state
|
||||
testb %al, %al
|
||||
/* everything failed, so restart from the beginning */
|
||||
jnz gate_a20_try_bios
|
||||
ret
|
||||
|
||||
gate_a20_check_state:
|
||||
/* iterate the checking for a while */
|
||||
movl $100, %ecx
|
||||
1:
|
||||
call 3f
|
||||
testb %al, %al
|
||||
jz 2f
|
||||
loop 1b
|
||||
2:
|
||||
ret
|
||||
3:
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
xorl %eax, %eax
|
||||
/* compare the byte at 0x8000 with that at 0x108000 */
|
||||
movl $VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR, %ebx
|
||||
pushl %ebx
|
||||
/* save the original byte in CL */
|
||||
movb (%ebx), %cl
|
||||
/* store the value at 0x108000 in AL */
|
||||
addl $0x100000, %ebx
|
||||
movb (%ebx), %al
|
||||
/* try to set one less value at 0x8000 */
|
||||
popl %ebx
|
||||
movb %al, %ch
|
||||
decb %ch
|
||||
movb %ch, (%ebx)
|
||||
/* serialize */
|
||||
outb %al, $0x80
|
||||
outb %al, $0x80
|
||||
/* obtain the value at 0x108000 in CH */
|
||||
pushl %ebx
|
||||
addl $0x100000, %ebx
|
||||
movb (%ebx), %ch
|
||||
/* this result is 0 if A20 is on or 1 if it is off */
|
||||
subb %ch, %al
|
||||
/* restore the original */
|
||||
popl %ebx
|
||||
movb %cl, (%ebx)
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
LOCAL(reed_solomon_part):
|
||||
|
||||
/*
|
||||
* Support for booting VAS_EBOOT from a Multiboot boot loader (e.g. VAS_EBOOT itself).
|
||||
* This uses the a.out kludge to load raw binary to the area starting at 1MB,
|
||||
* and relocates itself after loaded.
|
||||
*/
|
||||
.p2align 2 /* force 4-byte alignment */
|
||||
multiboot_header:
|
||||
/* magic */
|
||||
.long 0x1BADB002
|
||||
/* flags */
|
||||
.long (1 << 16)
|
||||
/* checksum */
|
||||
.long -0x1BADB002 - (1 << 16)
|
||||
/* header addr */
|
||||
.long multiboot_header - _start + 0x100000 + 0x200
|
||||
/* load addr */
|
||||
.long 0x100000
|
||||
/* load end addr */
|
||||
.long 0
|
||||
/* bss end addr */
|
||||
.long 0
|
||||
/* entry addr */
|
||||
.long multiboot_entry - _start + 0x100000 + 0x200
|
||||
|
||||
multiboot_entry:
|
||||
.code32
|
||||
/* obtain the boot device */
|
||||
movl 12(%ebx), %edx
|
||||
|
||||
movl $VAS_EBOOT_MEMORY_MACHINE_PROT_STACK, %ebp
|
||||
movl %ebp, %esp
|
||||
|
||||
/* relocate the code */
|
||||
#ifdef __APPLE__
|
||||
LOCAL(compressed_size_offset) = LOCAL(compressed_size) - LOCAL(base)
|
||||
movl $0x200, %ecx
|
||||
addl $decompressor_end, %ecx
|
||||
subl $LOCAL(base), %ecx
|
||||
addl LOCAL(compressed_size_offset) + 0x100000 + 0x200, %ecx
|
||||
#else
|
||||
movl $(LOCAL(decompressor_end) - _start + 0x200), %ecx
|
||||
addl LOCAL(compressed_size) - _start + 0x100000 + 0x200, %ecx
|
||||
#endif
|
||||
movl $0x100000, %esi
|
||||
movl $VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR, %edi
|
||||
cld
|
||||
rep
|
||||
movsb
|
||||
/* jump to the real address */
|
||||
movl $multiboot_trampoline, %eax
|
||||
jmp *%eax
|
||||
|
||||
multiboot_trampoline:
|
||||
/* fill the boot information */
|
||||
movl %edx, LOCAL(boot_dev)
|
||||
shrl $24, %edx
|
||||
/* enter the usual booting */
|
||||
call prot_to_real
|
||||
.code16
|
||||
jmp LOCAL (codestart)
|
||||
.code32
|
||||
|
||||
post_reed_solomon:
|
||||
|
||||
#ifdef ENABLE_LZMA
|
||||
movl $VAS_EBOOT_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
|
||||
#ifdef __APPLE__
|
||||
movl $decompressor_end, %esi
|
||||
#else
|
||||
movl $LOCAL(decompressor_end), %esi
|
||||
#endif
|
||||
pushl %edi
|
||||
movl LOCAL (uncompressed_size), %ecx
|
||||
leal (%edi, %ecx), %ebx
|
||||
/* Don't remove this push: it's an argument. */
|
||||
push %ecx
|
||||
call _LzmaDecodeA
|
||||
pop %ecx
|
||||
/* _LzmaDecodeA clears DF, so no need to run cld */
|
||||
popl %esi
|
||||
#endif
|
||||
|
||||
movl LOCAL(boot_dev), %edx
|
||||
movl $prot_to_real, %edi
|
||||
movl $real_to_prot, %ecx
|
||||
movl $LOCAL(realidt), %eax
|
||||
jmp *%esi
|
||||
|
||||
#ifdef ENABLE_LZMA
|
||||
#include "lzma_decode.S"
|
||||
#endif
|
||||
|
||||
.p2align 4
|
||||
|
||||
#ifdef __APPLE__
|
||||
.zerofill __DATA, __aa_before_bss, decompressor_end, 10, 0
|
||||
#else
|
||||
.bss
|
||||
LOCAL(decompressor_end):
|
||||
#endif
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <VasEBoot/symbol.h>
|
||||
#include <VasEBoot/machine/memory.h>
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
#include <VasEBoot/machine/kernel.h>
|
||||
|
||||
.text
|
||||
.code16
|
||||
.globl _start
|
||||
_start:
|
||||
/* Disable interrupts. */
|
||||
cli
|
||||
|
||||
jmp 1f
|
||||
|
||||
.org VAS_EBOOT_BOOT_I386_QEMU_CORE_ENTRY_ADDR
|
||||
VARIABLE(VasEBoot_core_entry_addr)
|
||||
.long 0
|
||||
1:
|
||||
|
||||
/* Set up %ds, %ss, and %es. */
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %ss
|
||||
movw %ax, %es
|
||||
|
||||
/* Set up the real mode stack. */
|
||||
movl $VAS_EBOOT_MEMORY_MACHINE_REAL_STACK, %esp
|
||||
|
||||
/* Transition to protected mode. We use pushl to force generation
|
||||
of a flat return address. */
|
||||
pushl $1f
|
||||
jmp real_to_prot
|
||||
.code32
|
||||
1:
|
||||
/* Ensure A20 is enabled. We're in qemu, so control port A works
|
||||
and there is no need to wait since there is no real logic, it's
|
||||
all emulated. */
|
||||
inb $0x92
|
||||
andb $(~0x03), %al
|
||||
orb $0x02, %al
|
||||
outb $0x92
|
||||
movl EXT_C(VasEBoot_core_entry_addr), %edx
|
||||
jmp *%edx
|
||||
|
||||
#include "../../../kern/i386/realmode.S"
|
||||
|
||||
/* Intel, in its infinite wisdom, decided to put the i8086 entry point
|
||||
*right here* and this is why we need this kludge. */
|
||||
|
||||
.org VAS_EBOOT_BOOT_MACHINE_SIZE - 16
|
||||
|
||||
.code16
|
||||
|
||||
jmp _start
|
||||
.org VAS_EBOOT_BOOT_MACHINE_SIZE
|
||||
|
|
@ -0,0 +1,756 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/mips/loongson/serial.h>
|
||||
#include <VasEBoot/mips/loongson/pci.h>
|
||||
#include <VasEBoot/mips/loongson.h>
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/machine/serial.h>
|
||||
#include <VasEBoot/machine/kernel.h>
|
||||
#include <VasEBoot/ns8250.h>
|
||||
#include <VasEBoot/cs5536.h>
|
||||
#include <VasEBoot/smbus.h>
|
||||
|
||||
#ifndef FULOONG2F
|
||||
#include <VasEBoot/vgaregs.h>
|
||||
#define VAS_EBOOT_SM712_REG_BASE 0x700000
|
||||
#define VAS_EBOOT_SM712_PCIID 0x0712126f
|
||||
#endif
|
||||
|
||||
#ifdef FULOONG2F
|
||||
#define VAS_EBOOT_MACHINE_SERIAL_PORT VAS_EBOOT_MACHINE_SERIAL_PORT2
|
||||
#define VAS_EBOOT_MACHINE_SERIAL_DIVISOR_115200 VAS_EBOOT_MACHINE_SERIAL_PORT2_DIVISOR_115200
|
||||
#else
|
||||
#define VAS_EBOOT_MACHINE_SERIAL_PORT VAS_EBOOT_MACHINE_SERIAL_PORT0
|
||||
#define VAS_EBOOT_MACHINE_SERIAL_DIVISOR_115200 VAS_EBOOT_MACHINE_SERIAL_PORT0_DIVISOR_115200
|
||||
#endif
|
||||
|
||||
.set noreorder
|
||||
.set noat
|
||||
.set nomacro
|
||||
.set mips3
|
||||
|
||||
.global start,_start,__start
|
||||
start:
|
||||
_start:
|
||||
__start:
|
||||
/* Put serial init as soon as possible. But on Fuloong2f serial is past
|
||||
Geode, so on Fuloong2f we need Geode first.
|
||||
*/
|
||||
#ifndef FULOONG2F
|
||||
bal serial_hw_init
|
||||
nop
|
||||
#endif
|
||||
|
||||
/* Find CS5536 controller. */
|
||||
/* $t4 chooses device in priority encoding. */
|
||||
/* Resulting value is kept in VAS_EBOOT_MACHINE_PCI_CONF_CTRL_REG.
|
||||
This way we don't need to sacrifice a register for it. */
|
||||
retry_cs5536:
|
||||
/* We have only one bus (0). Function is 0. */
|
||||
lui $t0, %hi(VAS_EBOOT_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F)
|
||||
lui $t1, %hi(VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F)
|
||||
lui $t3, %hi(VAS_EBOOT_CS5536_PCIID)
|
||||
addiu $t3, $t3, %lo(VAS_EBOOT_CS5536_PCIID)
|
||||
ori $t4, $zero, 1
|
||||
1:
|
||||
andi $t4, $t4, ((1 << VAS_EBOOT_PCI_NUM_DEVICES_2F) - 1)
|
||||
/* In case of failure try again. CS5536 may be slow to come up. */
|
||||
beql $t4, $zero, retry_cs5536
|
||||
nop
|
||||
sw $t4, %lo(VAS_EBOOT_MACHINE_PCI_CONF_CTRL_REG_ADDR_2F) ($t0)
|
||||
lw $t2, (%lo(VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F) + VAS_EBOOT_PCI_REG_PCI_ID) ($t1)
|
||||
bnel $t2, $t3, 1b
|
||||
sll $t4, $t4, 1
|
||||
|
||||
#ifndef FULOONG2F
|
||||
lui $a0, %hi(cs5536_found)
|
||||
bal message
|
||||
addiu $a0, $a0, %lo(cs5536_found)
|
||||
bal printhex
|
||||
move $a0, $t4
|
||||
#endif
|
||||
|
||||
lui $t0, %hi(VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F)
|
||||
li $t1, VAS_EBOOT_CS5536_MSR_MAILBOX_CONFIG_ENABLED
|
||||
sw $t1, (%lo(VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F) + VAS_EBOOT_CS5536_MSR_MAILBOX_CONFIG) ($t0)
|
||||
|
||||
/* Set GPIO LBAR. */
|
||||
lui $a0, %hi(VAS_EBOOT_CS5536_MSR_GPIO_BAR)
|
||||
addiu $a0, $a0, %lo(VAS_EBOOT_CS5536_MSR_GPIO_BAR)
|
||||
ori $a1, $zero, VAS_EBOOT_CS5536_LBAR_GPIO
|
||||
/* Set mask to 0xf and enabled bit to 1. */
|
||||
bal wrmsr
|
||||
ori $a2, $zero, ((VAS_EBOOT_CS5536_LBAR_MASK_MASK \
|
||||
| VAS_EBOOT_CS5536_LBAR_ENABLE) >> 32)
|
||||
|
||||
bal gpio_init
|
||||
nop
|
||||
|
||||
#ifdef FULOONG2F
|
||||
bal serial_hw_init
|
||||
nop
|
||||
#endif
|
||||
|
||||
/* Initialise SMBus controller. */
|
||||
/* Set SMBUS LBAR. */
|
||||
lui $a0, %hi(VAS_EBOOT_CS5536_MSR_SMB_BAR)
|
||||
addiu $a0, $a0, %lo(VAS_EBOOT_CS5536_MSR_SMB_BAR)
|
||||
ori $a1, $zero, VAS_EBOOT_CS5536_LBAR_SMBUS
|
||||
/* Set mask to 0xf and enabled bit to 1. */
|
||||
bal wrmsr
|
||||
ori $a2, $zero, ((VAS_EBOOT_CS5536_LBAR_MASK_MASK \
|
||||
| VAS_EBOOT_CS5536_LBAR_ENABLE) >> 32)
|
||||
|
||||
lui $a0, %hi(smbus_enabled)
|
||||
bal message
|
||||
addiu $a0, $a0, %lo(smbus_enabled)
|
||||
|
||||
lui $t0, %hi(VAS_EBOOT_MACHINE_PCI_IO_BASE_2F + VAS_EBOOT_CS5536_LBAR_SMBUS)
|
||||
|
||||
/* Disable SMB. */
|
||||
sb $zero, %lo(VAS_EBOOT_MACHINE_PCI_IO_BASE_2F + VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL2) ($t0)
|
||||
|
||||
/* Disable interrupts. */
|
||||
sb $zero, %lo(VAS_EBOOT_MACHINE_PCI_IO_BASE_2F + VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1) ($t0)
|
||||
|
||||
/* Set as master. */
|
||||
sb $zero, %lo(VAS_EBOOT_MACHINE_PCI_IO_BASE_2F + VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_ADDR) ($t0)
|
||||
|
||||
/* Launch SMBus controller at slowest speed possible. */
|
||||
ori $t1, $zero, 0xff
|
||||
sb $t1, %lo(VAS_EBOOT_MACHINE_PCI_IO_BASE_2F + VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL3) ($t0)
|
||||
sb $t1, %lo(VAS_EBOOT_MACHINE_PCI_IO_BASE_2F + VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL2) ($t0)
|
||||
|
||||
/* Yeeloong and Fuloong2f have only one memory slot. */
|
||||
/* Output first byte on serial for debugging. */
|
||||
ori $a1, $zero, VAS_EBOOT_SMB_RAM_START_ADDR
|
||||
bal read_spd
|
||||
move $a0, $zero
|
||||
bal printhex
|
||||
move $a0, $v0
|
||||
|
||||
bal read_spd
|
||||
ori $a0, $zero, VAS_EBOOT_SMBUS_SPD_MEMORY_TYPE_ADDR
|
||||
ori $t0, $zero, VAS_EBOOT_SMBUS_SPD_MEMORY_TYPE_DDR2
|
||||
lui $a0, %hi(unimplemented_memory_type)
|
||||
bne $t0, $v0, fatal
|
||||
addiu $a0, $a0, %lo(unimplemented_memory_type)
|
||||
|
||||
/* And here is our goal: DDR2 controller initialisation. */
|
||||
lui $t0, %hi(VAS_EBOOT_CPU_LOONGSON_CORECFG)
|
||||
ld $t1, %lo(VAS_EBOOT_CPU_LOONGSON_CORECFG) ($t0)
|
||||
/* Use addiu for sign-extension. */
|
||||
addiu $t2, $zero, ~(VAS_EBOOT_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE|VAS_EBOOT_CPU_LOONGSON_CORECFG_BUFFER_CPU)
|
||||
and $t1, $t1, $t2
|
||||
sd $t1, %lo (VAS_EBOOT_CPU_LOONGSON_CORECFG) ($t0)
|
||||
|
||||
b continue
|
||||
|
||||
.org VAS_EBOOT_CPU_LOONGSON_FLASH_TLB_REFILL - VAS_EBOOT_CPU_LOONGSON_FLASH_START
|
||||
tlb_refill:
|
||||
mfc0 $s1, VAS_EBOOT_CPU_LOONGSON_COP0_EPC
|
||||
mfc0 $s2, VAS_EBOOT_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)
|
||||
|
||||
.org VAS_EBOOT_CPU_LOONGSON_FLASH_CACHE_ERROR - VAS_EBOOT_CPU_LOONGSON_FLASH_START
|
||||
cache_error:
|
||||
lui $a0, %hi(unhandled_cache_error)
|
||||
b fatal
|
||||
addiu $a0, $a0, %lo(unhandled_cache_error)
|
||||
|
||||
.org VAS_EBOOT_CPU_LOONGSON_FLASH_OTHER_EXCEPTION - VAS_EBOOT_CPU_LOONGSON_FLASH_START
|
||||
other_exception:
|
||||
mfc0 $s0, VAS_EBOOT_CPU_LOONGSON_COP0_CAUSE
|
||||
mfc0 $s1, VAS_EBOOT_CPU_LOONGSON_COP0_EPC
|
||||
mfc0 $s2, VAS_EBOOT_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)
|
||||
|
||||
gpio_init:
|
||||
lui $t0, %hi(VAS_EBOOT_MACHINE_PCI_IO_BASE_2F + VAS_EBOOT_CS5536_LBAR_GPIO)
|
||||
addiu $t0, $t0, %lo(VAS_EBOOT_MACHINE_PCI_IO_BASE_2F + VAS_EBOOT_CS5536_LBAR_GPIO)
|
||||
lui $t1, %hi (gpio_dump)
|
||||
addiu $t1, $t1, %lo (gpio_dump)
|
||||
|
||||
1:
|
||||
lw $t2, 0($t1)
|
||||
sw $t2, 0($t0)
|
||||
addiu $t0, $t0, 4
|
||||
addiu $t1, $t1, 4
|
||||
lui $t2, %hi (gpio_dump_end)
|
||||
addiu $t2, $t2, %lo (gpio_dump_end)
|
||||
bne $t1, $t2, 1b
|
||||
nop
|
||||
jr $ra
|
||||
nop
|
||||
|
||||
/* Same as similarly named C function but in asm since
|
||||
we need it early. */
|
||||
/* In: none. Out: none. Clobbered: $t0, $t1, $t2, $a0, $a1, $a2. */
|
||||
serial_hw_init:
|
||||
move $t2, $ra
|
||||
#ifdef FULOONG2F
|
||||
lui $a0, %hi(VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO)
|
||||
addiu $a0, $a0, %lo(VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO)
|
||||
lui $a1, %hi (VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3 \
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_F_REMAP \
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 \
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1)
|
||||
ori $a1, $a1, (VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 \
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1)
|
||||
bal wrmsr
|
||||
move $a2, $zero
|
||||
|
||||
lui $a0, %hi(VAS_EBOOT_CS5536_MSR_DIVIL_UART1_CONF)
|
||||
addiu $a0, $a0, %lo(VAS_EBOOT_CS5536_MSR_DIVIL_UART1_CONF)
|
||||
li $a1, 2
|
||||
bal wrmsr
|
||||
move $a2, $zero
|
||||
|
||||
lui $a0, %hi(VAS_EBOOT_CS5536_MSR_DIVIL_UART2_CONF)
|
||||
addiu $a0, $a0, %lo(VAS_EBOOT_CS5536_MSR_DIVIL_UART2_CONF)
|
||||
li $a1, 2
|
||||
bal wrmsr
|
||||
move $a2, $zero
|
||||
#endif
|
||||
|
||||
lui $t0, %hi (VAS_EBOOT_MACHINE_SERIAL_PORT)
|
||||
|
||||
/* Turn off the interrupt. */
|
||||
sb $zero, (%lo (VAS_EBOOT_MACHINE_SERIAL_PORT) + UART_IER)($t0)
|
||||
|
||||
/* Set DLAB. */
|
||||
ori $t1, $zero, UART_DLAB
|
||||
sb $t1, (%lo (VAS_EBOOT_MACHINE_SERIAL_PORT) + UART_LCR)($t0)
|
||||
|
||||
/* Set the baud rate 115200. */
|
||||
ori $t1, $zero, VAS_EBOOT_MACHINE_SERIAL_DIVISOR_115200
|
||||
sb $t1, (%lo (VAS_EBOOT_MACHINE_SERIAL_PORT) + UART_DLL)($t0)
|
||||
sb $zero, (%lo (VAS_EBOOT_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 (VAS_EBOOT_MACHINE_SERIAL_PORT) + UART_LCR)($t0)
|
||||
|
||||
/* Enable the FIFO. */
|
||||
ori $t1, $zero, UART_ENABLE_FIFO_TRIGGER1
|
||||
sb $t1, (%lo (VAS_EBOOT_MACHINE_SERIAL_PORT) + UART_FCR)($t0)
|
||||
|
||||
/* Turn on DTR and RTS. */
|
||||
ori $t1, $zero, UART_ENABLE_DTRRTS
|
||||
sb $t1, (%lo (VAS_EBOOT_MACHINE_SERIAL_PORT) + UART_MCR)($t0)
|
||||
|
||||
/* Let message return to original caller. */
|
||||
lui $a0, %hi(notification_string)
|
||||
addiu $a0, $a0, %lo(notification_string)
|
||||
move $ra, $t2
|
||||
|
||||
/* Print message on serial console. */
|
||||
/* In: $a0 = asciiz message. Out: none. Clobbered: $t0, $t1, $a0. */
|
||||
message:
|
||||
lui $t0, %hi (VAS_EBOOT_MACHINE_SERIAL_PORT)
|
||||
1:
|
||||
lb $t1, (%lo (VAS_EBOOT_MACHINE_SERIAL_PORT) + UART_LSR)($t0)
|
||||
andi $t1, $t1, UART_EMPTY_TRANSMITTER
|
||||
beq $t1, $zero, 1b
|
||||
nop
|
||||
lb $t1, 0($a0)
|
||||
sb $t1, (%lo (VAS_EBOOT_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 (VAS_EBOOT_MACHINE_SERIAL_PORT)
|
||||
ori $t2, $zero, 8
|
||||
1:
|
||||
lb $t1, (%lo (VAS_EBOOT_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
|
||||
bltz $t1, 2f
|
||||
sll $a0, $a0, 4
|
||||
addiu $t1, $t1, 'A'-10-'0'
|
||||
2: addiu $t1, $t1, '0'+10
|
||||
sb $t1, (%lo (VAS_EBOOT_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(VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F)
|
||||
sw $a0, (%lo(VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F) + VAS_EBOOT_CS5536_MSR_MAILBOX_ADDR) ($t0)
|
||||
sw $a1, (%lo(VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F) + VAS_EBOOT_CS5536_MSR_MAILBOX_DATA0) ($t0)
|
||||
jr $ra
|
||||
sw $a2, (%lo(VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F) + VAS_EBOOT_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(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_STATUS + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
lb $t0, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_STATUS + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
andi $t1, $t0, VAS_EBOOT_CS5536_SMB_REG_STATUS_SDAST
|
||||
bne $t1, $zero, return
|
||||
nop
|
||||
andi $t1, $t0, (VAS_EBOOT_CS5536_SMB_REG_STATUS_BER | VAS_EBOOT_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, %lo(read_spd_fail)
|
||||
|
||||
/* Send START. */
|
||||
lui $t0, %hi(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
lb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
ori $t1, $t1, VAS_EBOOT_CS5536_SMB_REG_CTRL1_START
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
|
||||
/* Send device address. */
|
||||
lui $t0, %hi(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_DATA + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
sll $t1, $a1, 1
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_DATA + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
|
||||
/* Send ACK. */
|
||||
lui $t0, %hi(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
lb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
ori $t1, $t1, VAS_EBOOT_CS5536_SMB_REG_CTRL1_ACK
|
||||
sb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
|
||||
/* Send byte address. */
|
||||
lui $t0, %hi(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_DATA + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
bal smbus_wait
|
||||
sb $t2, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_DATA + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
|
||||
/* Send START. */
|
||||
lui $t0, %hi(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
lb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
ori $t1, $t1, VAS_EBOOT_CS5536_SMB_REG_CTRL1_START
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
|
||||
/* Send device address. */
|
||||
lui $t0, %hi(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_DATA + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
sll $t1, $a1, 1
|
||||
ori $t1, $t1, 1
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_DATA + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
|
||||
/* Send STOP. */
|
||||
lui $t0, %hi(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
lb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
ori $t1, $t1, VAS_EBOOT_CS5536_SMB_REG_CTRL1_STOP
|
||||
bal smbus_wait
|
||||
sb $t1, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_CTRL1 + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
|
||||
lui $t0, %hi(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_DATA + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F)
|
||||
lb $v0, %lo(VAS_EBOOT_CS5536_LBAR_SMBUS + VAS_EBOOT_CS5536_SMB_REG_DATA + VAS_EBOOT_MACHINE_PCI_IO_BASE_2F) ($t0)
|
||||
jr $t3
|
||||
andi $v0, $v0, 0xff
|
||||
read_spd_fail:
|
||||
jr $t3
|
||||
ori $v0, $v0, 0x100
|
||||
|
||||
notification_string: .asciz "VAS_EBOOT "
|
||||
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 */
|
||||
#ifdef FULOONG2F
|
||||
.quad 0x0000000100000001 /* 8 */
|
||||
#else
|
||||
.quad 0x0000010200000102 /* 8 */
|
||||
#endif
|
||||
.quad 0x0000060c00000000 /* 9 */
|
||||
.quad 0x2323233f3f1f0200 /* a */
|
||||
.quad 0x5f7f232323232323 /* b */
|
||||
.quad 0x002a3c0615000000 /* c */
|
||||
.quad 0x002a002a002a002a /* d */
|
||||
.quad 0x002a002a002a002a /* e */
|
||||
#ifdef FULOONG2F
|
||||
.quad 0x00b40020005b0004 /* f */
|
||||
#else
|
||||
.quad 0x00b40020006d0004 /* f */
|
||||
#endif
|
||||
.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 */
|
||||
|
||||
/* Dump of GPIO connections. FIXME: Remove useless and macroify. */
|
||||
gpio_dump:
|
||||
#ifdef FULOONG2F
|
||||
.long 0xffff0000, 0x2eefd110, 0xffff0000, 0xffff0000
|
||||
.long 0x2eefd110, 0xffff0000, 0x1000efff, 0xefff1000
|
||||
.long 0x3df3c20c, 0xffff0000, 0xffff0000, 0xffff0000
|
||||
.long 0x7df3820c, 0x3df3c20c, 0xffff0000, 0x00000000
|
||||
.long 0xffff0000, 0xffff0000, 0x3de3c21c, 0x3d83c27c
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000
|
||||
.long 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000
|
||||
.long 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000
|
||||
.long 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000
|
||||
.long 0xffff0000, 0xffff0000, 0xefff1000, 0xefff1000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
#else
|
||||
.long 0xffff0000, 0x2ffdd002, 0xffff0000, 0xffff0000
|
||||
.long 0x2fffd000, 0xffff0000, 0x1000efff, 0xefff1000
|
||||
.long 0x3ffbc004, 0xffff0000, 0xffff0000, 0xffff0000
|
||||
.long 0x3ffbc004, 0x3ffbc004, 0xffff0000, 0x00000000
|
||||
.long 0xffff0000, 0xffff0000, 0x3ffbc004, 0x3f9bc064
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000
|
||||
.long 0xffff0000, 0xffff0000, 0x0000ffff, 0xffff0000
|
||||
.long 0xefff1000, 0xffff0000, 0xffff0000, 0xffff0000
|
||||
.long 0xefff1000, 0xefff1000, 0xffff0000, 0x00000000
|
||||
.long 0xffff0000, 0xffff0000, 0xefff1000, 0xffff0000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
.long 0x00000000, 0x50000000, 0x00000000, 0x00000000
|
||||
#endif
|
||||
gpio_dump_end:
|
||||
|
||||
.p2align 3
|
||||
|
||||
write_dumpreg:
|
||||
ld $t2, 0($t6)
|
||||
sd $t2, 0($t4)
|
||||
addiu $t4, $t4, VAS_EBOOT_CPU_LOONGSON_DDR2_REG_STEP
|
||||
jr $ra
|
||||
addiu $t6, $t6, VAS_EBOOT_CPU_LOONGSON_DDR2_REG_SIZE
|
||||
|
||||
continue:
|
||||
lui $t4, %hi(VAS_EBOOT_CPU_LOONGSON_DDR2_BASE)
|
||||
addiu $t4, $t4, %lo(VAS_EBOOT_CPU_LOONGSON_DDR2_BASE)
|
||||
lui $t6, %hi(regdump)
|
||||
|
||||
/* 0 */
|
||||
bal write_dumpreg
|
||||
addiu $t6, $t6, %lo(regdump)
|
||||
|
||||
/* 1 */
|
||||
ori $a1, $a1, VAS_EBOOT_SMB_RAM_START_ADDR
|
||||
move $t8, $zero
|
||||
lui $t5, 0x0001
|
||||
bal read_spd
|
||||
ori $a0, $zero, VAS_EBOOT_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR
|
||||
ori $t7, $zero, 8
|
||||
bne $v0, $t7, 1f
|
||||
ori $t5, $t5, 0x0001
|
||||
ori $t8, $t8, VAS_EBOOT_CPU_LOONGSON_DDR2_REG1_HI_8BANKS
|
||||
1:
|
||||
dsll $t8, $t8, 32
|
||||
or $t5, $t5, $t8
|
||||
sd $t5, 0 ($t4)
|
||||
addiu $t4, $t4, VAS_EBOOT_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, VAS_EBOOT_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, VAS_EBOOT_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR
|
||||
ori $t0, $zero, VAS_EBOOT_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE
|
||||
ori $t1, $zero, (1 << VAS_EBOOT_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, VAS_EBOOT_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, VAS_EBOOT_CPU_LOONGSON_DDR2_REG_STEP
|
||||
|
||||
ori $t7, $zero, 0x16
|
||||
|
||||
1:
|
||||
ld $t2, 0($t6)
|
||||
sd $t2, 0($t4)
|
||||
addiu $t4, $t4, VAS_EBOOT_CPU_LOONGSON_DDR2_REG_STEP
|
||||
addiu $t7, $t7, -1
|
||||
bne $t7, $zero, 1b
|
||||
addiu $t6, $t6, VAS_EBOOT_CPU_LOONGSON_DDR2_REG_SIZE
|
||||
|
||||
lui $t4, %hi(VAS_EBOOT_CPU_LOONGSON_DDR2_BASE)
|
||||
ld $t5, (%lo(VAS_EBOOT_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4)
|
||||
ori $t0, $zero, 1
|
||||
dsll $t0, $t0, 40
|
||||
or $t5, $t5, $t0
|
||||
sd $t5, (%lo(VAS_EBOOT_CPU_LOONGSON_DDR2_BASE) + 0x30) ($t4)
|
||||
|
||||
/* Desactivate DDR2 registers. */
|
||||
lui $t0, %hi (VAS_EBOOT_CPU_LOONGSON_CORECFG)
|
||||
ld $t1, %lo (VAS_EBOOT_CPU_LOONGSON_CORECFG) ($t0)
|
||||
ori $t1, $t1, VAS_EBOOT_CPU_LOONGSON_CORECFG_DISABLE_DDR2_SPACE
|
||||
sd $t1, %lo (VAS_EBOOT_CPU_LOONGSON_CORECFG) ($t0)
|
||||
|
||||
/* Enable cache. */
|
||||
mfc0 $t0, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_CONFIG
|
||||
addiu $t1, $zero, ~VAS_EBOOT_CPU_LOONGSON_CACHE_TYPE_MASK
|
||||
and $t0, $t1, $t1
|
||||
/* Set line size to 32 bytes and disabled cache. */
|
||||
ori $t0, $t0, (VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_CONFIG_ILINESIZE \
|
||||
| VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_CONFIG_DLINESIZE \
|
||||
| VAS_EBOOT_CPU_LOONGSON_CACHE_ACCELERATED)
|
||||
mtc0 $t0, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_CONFIG
|
||||
|
||||
/* Invalidate all I-cache entries. */
|
||||
srl $t1, $t0, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_ISIZE_SHIFT
|
||||
andi $t1, $t1, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
|
||||
ori $t2, $zero, (1 << (VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
|
||||
- VAS_EBOOT_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
|
||||
- VAS_EBOOT_CPU_LOONGSON_I_CACHE_LOG_WAYS))
|
||||
sll $t1, $t2, $t1
|
||||
lui $t2, 0x8000
|
||||
|
||||
1:
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_I_INDEX_INVALIDATE, 0($t2)
|
||||
addiu $t1, $t1, -1
|
||||
bne $t1, $zero, 1b
|
||||
addiu $t2, $t2, (1 << VAS_EBOOT_CPU_LOONGSON_COP0_I_INDEX_BIT_OFFSET)
|
||||
|
||||
/* Invalidate all D-cache entries. */
|
||||
srl $t1, $t0, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_DSIZE_SHIFT
|
||||
andi $t1, $t1, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_SIZE_MASK
|
||||
ori $t2, $zero, (1 << (VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_SIZE_OFFSET \
|
||||
- VAS_EBOOT_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
|
||||
- VAS_EBOOT_CPU_LOONGSON_D_CACHE_LOG_WAYS))
|
||||
sll $t1, $t2, $t1
|
||||
lui $t2, 0x8000
|
||||
mtc0 $zero, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_TAGLO
|
||||
mtc0 $zero, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_TAGHI
|
||||
1:
|
||||
/* All four ways. */
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 0($t2)
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 1($t2)
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 2($t2)
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_D_INDEX_TAG_STORE, 3($t2)
|
||||
addiu $t1, $t1, -1
|
||||
bne $t1, $zero, 1b
|
||||
addiu $t2, $t2, (1 << VAS_EBOOT_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
|
||||
|
||||
/* Invalidate all S-cache entries. */
|
||||
ori $t1, $zero, (1 << (VAS_EBOOT_CPU_LOONGSON_SECONDARY_CACHE_LOG_SIZE \
|
||||
- VAS_EBOOT_CPU_LOONGSON_CACHE_LINE_SIZE_LOG_BIG \
|
||||
- VAS_EBOOT_CPU_LOONGSON_S_CACHE_LOG_WAYS))
|
||||
lui $t2, 0x8000
|
||||
mtc0 $zero, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_TAGLO
|
||||
mtc0 $zero, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_TAGHI
|
||||
1:
|
||||
/* All four ways. */
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 0($t2)
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 1($t2)
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 2($t2)
|
||||
cache VAS_EBOOT_CPU_LOONGSON_COP0_S_INDEX_TAG_STORE, 3($t2)
|
||||
addiu $t1, $t1, -1
|
||||
bne $t1, $zero, 1b
|
||||
addiu $t2, $t2, (1 << VAS_EBOOT_CPU_LOONGSON_COP0_D_INDEX_BIT_OFFSET)
|
||||
|
||||
/* Finally enable cache. */
|
||||
mfc0 $t0, VAS_EBOOT_CPU_LOONGSON_COP0_CACHE_CONFIG
|
||||
addiu $t1, $zero, ~VAS_EBOOT_CPU_LOONGSON_CACHE_TYPE_MASK
|
||||
and $t0, $t1, $t1
|
||||
ori $t0, $t0, VAS_EBOOT_CPU_LOONGSON_CACHE_CACHED
|
||||
mtc0 $t0, VAS_EBOOT_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(VAS_EBOOT_CPU_LOONGSON_LIOCFG)
|
||||
lw $t1, %lo(VAS_EBOOT_CPU_LOONGSON_LIOCFG) ($t0)
|
||||
addiu $t2, $zero, ~(VAS_EBOOT_CPU_LOONGSON_ROM_DELAY_MASK \
|
||||
<< VAS_EBOOT_CPU_LOONGSON_ROM_DELAY_OFFSET)
|
||||
and $t1, $t1, $t2
|
||||
ori $t1, $t1, (1 << VAS_EBOOT_CPU_LOONGSON_ROM_DELAY_OFFSET)
|
||||
sw $t1, %lo(VAS_EBOOT_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
|
||||
#ifdef FULOONG2F
|
||||
addiu $a2, $zero, -(1 + VAS_EBOOT_ARCH_MACHINE_FULOONG2F)
|
||||
#else
|
||||
addiu $a2, $zero, -(1 + VAS_EBOOT_ARCH_MACHINE_YEELOONG)
|
||||
#endif
|
||||
|
||||
cached_continue:
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
/* startup.S - Startup code for the MIPS. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/symbol.h>
|
||||
#include <VasEBoot/offsets.h>
|
||||
#include <VasEBoot/machine/memory.h>
|
||||
#include <VasEBoot/machine/kernel.h>
|
||||
#include <VasEBoot/offsets.h>
|
||||
#include <VasEBoot/mips/asm.h>
|
||||
|
||||
#define BASE_ADDR 8
|
||||
|
||||
.extern __bss_start
|
||||
.extern _end
|
||||
.extern _edata
|
||||
|
||||
.globl __start, _start, start
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
__start:
|
||||
_start:
|
||||
start:
|
||||
|
||||
bal codestart
|
||||
nop
|
||||
base:
|
||||
.org VAS_EBOOT_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
|
||||
compressed_size:
|
||||
.long 0
|
||||
.org VAS_EBOOT_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
|
||||
uncompressed_size:
|
||||
.long 0
|
||||
.org VAS_EBOOT_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR
|
||||
uncompressed_addr:
|
||||
.long 0
|
||||
codestart:
|
||||
/* Save our base. */
|
||||
move $s0, $ra
|
||||
|
||||
/* Parse arguments. Has to be done before relocation.
|
||||
So need to do it in asm. */
|
||||
#ifdef VAS_EBOOT_MACHINE_MIPS_QEMU_MIPS
|
||||
lui $t0, %hi (((16 << 20) - 264 + 4) | 0x80000000)
|
||||
lw $t1, %lo (((16 << 20) - 264 + 4) | 0x80000000) ($t0)
|
||||
|
||||
lui $t2, 0x1234
|
||||
ori $t2, 0x5678
|
||||
|
||||
bne $t1, $t2, 1f
|
||||
nop
|
||||
|
||||
lui $t0, %hi (((16 << 20) - 264) | 0x80000000)
|
||||
b 2f
|
||||
lw $s4, %lo (((16 << 20) - 264) | 0x80000000) ($t0)
|
||||
|
||||
1:
|
||||
li $s4, 0
|
||||
2:
|
||||
#endif
|
||||
|
||||
#ifdef VAS_EBOOT_MACHINE_MIPS_LOONGSON
|
||||
move $s2, $zero
|
||||
move $s3, $zero
|
||||
move $s4, $zero
|
||||
move $s5, $zero
|
||||
move $s7, $zero
|
||||
|
||||
/* $a2 has the environment. */
|
||||
addiu $t0, $zero, -0x10
|
||||
and $t1, $a2, $t0
|
||||
beq $t0, $t1, argfw
|
||||
nop
|
||||
move $t0, $a2
|
||||
argcont:
|
||||
lw $t1, 0($t0)
|
||||
beq $t1, $zero, argdone
|
||||
nop
|
||||
#define DO_PARSE(str, reg) \
|
||||
addiu $t2, $s0, (str-base);\
|
||||
bal parsestr;\
|
||||
nop ;\
|
||||
beq $v0, $zero, 1f;\
|
||||
nop ;\
|
||||
b 2f;\
|
||||
move reg, $v0; \
|
||||
1:
|
||||
#define DO_CHECKT1(str, val) \
|
||||
move $t6, $t1 ;\
|
||||
addiu $t7, $s0, (str - base);\
|
||||
bal do_check ;\
|
||||
li $t2, val
|
||||
|
||||
DO_PARSE (busclockstr, $s2)
|
||||
DO_PARSE (cpuclockstr, $s3)
|
||||
DO_PARSE (memsizestr, $s4)
|
||||
DO_PARSE (highmemsizestr, $s5)
|
||||
DO_CHECKT1 (pmon_yeeloong_verstr, VAS_EBOOT_ARCH_MACHINE_YEELOONG)
|
||||
DO_CHECKT1 (pmon_fuloong2f_verstr, VAS_EBOOT_ARCH_MACHINE_FULOONG2F)
|
||||
2:
|
||||
b argcont
|
||||
addiu $t0, $t0, 4
|
||||
parsestr:
|
||||
move $v0, $zero
|
||||
move $t3, $t1
|
||||
3:
|
||||
lb VAS_EBOOT_ASM_T4, 0($t2)
|
||||
lb VAS_EBOOT_ASM_T5, 0($t3)
|
||||
addiu $t2, $t2, 1
|
||||
addiu $t3, $t3, 1
|
||||
beq VAS_EBOOT_ASM_T5, $zero, 1f
|
||||
nop
|
||||
beq VAS_EBOOT_ASM_T5, VAS_EBOOT_ASM_T4, 3b
|
||||
nop
|
||||
bne VAS_EBOOT_ASM_T4, $zero, 1f
|
||||
nop
|
||||
|
||||
addiu $t3, $t3, 0xffff
|
||||
digcont:
|
||||
lb VAS_EBOOT_ASM_T5, 0($t3)
|
||||
/* Substract '0' from digit. */
|
||||
addiu VAS_EBOOT_ASM_T5, VAS_EBOOT_ASM_T5, 0xffd0
|
||||
bltz VAS_EBOOT_ASM_T5, 1f
|
||||
nop
|
||||
addiu VAS_EBOOT_ASM_T4, VAS_EBOOT_ASM_T5, 0xfff7
|
||||
bgtz VAS_EBOOT_ASM_T4, 1f
|
||||
nop
|
||||
/* Multiply $v0 by 10 with bitshifts. */
|
||||
sll $v0, $v0, 1
|
||||
sll VAS_EBOOT_ASM_T4, $v0, 2
|
||||
addu $v0, $v0, VAS_EBOOT_ASM_T4
|
||||
addu $v0, $v0, VAS_EBOOT_ASM_T5
|
||||
addiu $t3, $t3, 1
|
||||
b digcont
|
||||
nop
|
||||
1:
|
||||
jr $ra
|
||||
nop
|
||||
busclockstr: .asciz "busclock="
|
||||
cpuclockstr: .asciz "cpuclock="
|
||||
memsizestr: .asciz "memsize="
|
||||
highmemsizestr: .asciz "highmemsize="
|
||||
machtype_yeeloong_str1: .asciz "machtype=8.9"
|
||||
machtype_yeeloong_str2: .asciz "machtype=lemote-yeeloong-"
|
||||
machtype_fuloong2f_str: .asciz "machtype=lemote-fuloong-2f"
|
||||
machtype_fuloong2e_str: .asciz "machtype=lemote-fuloong-2e"
|
||||
pmon_yeeloong_str: .asciz "PMON_VER=LM8"
|
||||
pmon_fuloong2f_str: .asciz "PMON_VER=LM6"
|
||||
pmon_yeeloong_verstr: .asciz "Version=LM8"
|
||||
pmon_fuloong2f_verstr: .asciz "Version=LM6"
|
||||
.p2align 2
|
||||
|
||||
argdone:
|
||||
beq $a0, $zero, cmdlinedone
|
||||
nop
|
||||
#define DO_CHECKA1(str, val) \
|
||||
lw $t6, 0($a1) ;\
|
||||
addiu $t7, $s0, (str - base);\
|
||||
bal do_check ;\
|
||||
li $t2, val
|
||||
DO_CHECKA1 (machtype_yeeloong_str1, VAS_EBOOT_ARCH_MACHINE_YEELOONG)
|
||||
DO_CHECKA1 (machtype_yeeloong_str2, VAS_EBOOT_ARCH_MACHINE_YEELOONG)
|
||||
DO_CHECKA1 (pmon_yeeloong_str, VAS_EBOOT_ARCH_MACHINE_YEELOONG)
|
||||
DO_CHECKA1 (machtype_fuloong2f_str, VAS_EBOOT_ARCH_MACHINE_FULOONG2F)
|
||||
DO_CHECKA1 (machtype_fuloong2e_str, VAS_EBOOT_ARCH_MACHINE_FULOONG2E)
|
||||
DO_CHECKA1 (pmon_fuloong2f_str, VAS_EBOOT_ARCH_MACHINE_FULOONG2F)
|
||||
addiu $a0, $a0, -1
|
||||
b argdone
|
||||
addiu $a1, $a1, 4
|
||||
do_check:
|
||||
lb VAS_EBOOT_ASM_T4, 0($t7)
|
||||
beq VAS_EBOOT_ASM_T4, $zero, 1f
|
||||
lb $t3, 0($t6)
|
||||
bne $t3, VAS_EBOOT_ASM_T4, 2f
|
||||
addiu $t6, $t6, 1
|
||||
b do_check
|
||||
addiu $t7, $t7, 1
|
||||
1:
|
||||
move $s7, $t2
|
||||
2:
|
||||
jr $ra
|
||||
nop
|
||||
argfw:
|
||||
not $s7, $a2
|
||||
cmdlinedone:
|
||||
#endif
|
||||
#ifdef VAS_EBOOT_MACHINE_ARC
|
||||
lui $t0, %hi(_start - 256)
|
||||
addiu $t0, $t0, %lo(_start - 256)
|
||||
addiu $t3, $t0, 255
|
||||
lw $t1, 0($a1)
|
||||
1:
|
||||
bne $t0, $t3, 2f
|
||||
lb $t2, 0($t1)
|
||||
move $t2, $zero
|
||||
2:
|
||||
sb $t2, 0($t0)
|
||||
addiu $t0, $t0, 1
|
||||
bnez $t2, 1b
|
||||
addiu $t1, $t1, 1
|
||||
#endif
|
||||
/* Copy the decompressor. */
|
||||
lui $t1, %hi(base)
|
||||
addiu $t1, $t1, %lo(base)
|
||||
lui $t3, %hi(__bss_start)
|
||||
addiu $t3, $t3, %lo(__bss_start)
|
||||
move $t2, $s0
|
||||
|
||||
1:
|
||||
beq $t1, $t3, 2f
|
||||
lb VAS_EBOOT_ASM_T4, 0($t2)
|
||||
sb VAS_EBOOT_ASM_T4, 0($t1)
|
||||
addiu $t1, $t1, 1
|
||||
b 1b
|
||||
addiu $t2, $t2, 1
|
||||
2:
|
||||
/* Clean out its BSS. */
|
||||
lui $t1, %hi(__bss_start)
|
||||
addiu $t1, $t1, %lo(__bss_start)
|
||||
lui $t2, %hi(_end)
|
||||
addiu $t2, $t2, %lo(_end)
|
||||
1:
|
||||
beq $t1, $t2, 2f
|
||||
nop
|
||||
sb $zero, 0($t1)
|
||||
b 1b
|
||||
addiu $t1, $t1, 1
|
||||
2:
|
||||
lui $a0, %hi(base)
|
||||
addiu $a0, $a0, %lo(base)
|
||||
lui $a1, %hi(_end)
|
||||
addiu $a1, %lo(_end)
|
||||
subu $a1,$a1,$a0
|
||||
|
||||
#include "../../kern/mips/cache_flush.S"
|
||||
|
||||
/* Decompress the payload. */
|
||||
lui $a0, %hi(_edata)
|
||||
addiu $a0, $a0, %lo(_edata)
|
||||
|
||||
lui $t0, %hi(base)
|
||||
addiu $t0, $t0, %lo(base)
|
||||
subu $a0, $a0, $t0
|
||||
addu $a0, $a0, $s0
|
||||
|
||||
lw $a1, (VAS_EBOOT_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR - BASE_ADDR)($s0)
|
||||
lw $a2, (VAS_EBOOT_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0)
|
||||
lw $a3, (VAS_EBOOT_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE - BASE_ADDR)($s0)
|
||||
move $s1, $a1
|
||||
|
||||
/* $a0 contains source compressed address, $a1 is destination,
|
||||
$a2 is compressed size, $a3 is uncompressed size.
|
||||
*/
|
||||
move $s6, $a3
|
||||
|
||||
lui $t9, %hi(EXT_C(VasEBoot_decompress_core))
|
||||
addiu $t9, $t9, %lo(EXT_C(VasEBoot_decompress_core))
|
||||
|
||||
#ifdef VAS_EBOOT_MACHINE_ARC
|
||||
lui $sp, %hi(_start - 512)
|
||||
jalr $t9
|
||||
addiu $sp, $sp, %lo(_start - 512)
|
||||
#else
|
||||
lui $sp, %hi(_start - 256)
|
||||
jalr $t9
|
||||
addiu $sp, $sp, %lo(_start - 256)
|
||||
#endif
|
||||
move $a0, $s1
|
||||
move $a1, $s6
|
||||
|
||||
#include "../../kern/mips/cache_flush.S"
|
||||
|
||||
lui $t1, %hi(VAS_EBOOT_MACHINE_LINK_ADDR)
|
||||
addiu $t1, %lo(VAS_EBOOT_MACHINE_LINK_ADDR)
|
||||
|
||||
jr $t1
|
||||
nop
|
||||
/* Ensure that .data section is created. In code we suppose that _edata
|
||||
is first location not in decompressor image. Strictly speaking it's
|
||||
_edata only when .data is present and _etext otherwise. But checking
|
||||
for .data presence would cost more in code than it is to ensure that
|
||||
.data is created.
|
||||
*/
|
||||
.data
|
||||
.long 0
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
<CHRP-BOOT>
|
||||
<COMPATIBLE>
|
||||
MacRISC MacRISC3 MacRISC4
|
||||
</COMPATIBLE>
|
||||
<DESCRIPTION>
|
||||
@PACKAGE@ @VERSION@
|
||||
</DESCRIPTION>
|
||||
<OS-BADGE-ICONS>
|
||||
3434
|
||||
00000000000000F781FB8181818181FBFAF500000000000000000000000000000000000000F6FAFAFAFA81F9F600000000000000
|
||||
0000000000F8FBF9F500F95656FCFB5656FBF800000000000000000000000000000000F5FAF9F5F7F600F6F6F9FAF70000000000
|
||||
000000F5FBFA0056FDFEFEFDFDFAAC81FB56568181560000000000000000000000F9F9F9F7FCFDFEFEFEFFFC81F656FA00000000
|
||||
0000F5AC2BF7FBFEFEFD2BF6568181F9F7F6F6F8FBF50000000000000000000000FAF700F600F5F7F7F6F7FEFFACF82BFB000000
|
||||
0000FC2BF5FEFFFFF5F7FC81F70000F7F9FAFAF8000000000000000000000000000056F9F9FAF9F7F7FA812BF7FFFF56F7FA0000
|
||||
005656F5FEFFAC2BF9FA000000000000000000000000000000000000000000000000000000000000000000FA56FAFEFEF8F9F700
|
||||
00FB00F7FFFF56F9F800000000000000000000F656FAFA56F50000000000F5F8F9F8F5000000000000000000F9F7FCFFFB00FB00
|
||||
F8F800ACFFACF6FA000000000000000000F6FA562BF5F5F781FA000000F9FA2B00F556F9F5000000000000000081F8FFFEF6562B
|
||||
810000FFFFF9FAF500000000000000002B8100F5F9FCACFBF82BFBF6FCFAF6FAFC81F600FA2B000000000000002BF8FEFFF8F5FA
|
||||
FA00F5FEFFFA8100000000000000002B8100F9FEFFFFFFFFFFFBF6FDFEACFDFEFFFFFFFBF581F600000000000000F9FEFFF700FA
|
||||
FA00FBFFFEF6F900000000000000F6FB00FCFFFFFFFFFFFFFFFFFCF600FCF7ACFEFFFFFFFDF6810000000000000056F9FFAC00FA
|
||||
FA00F6FFFFF856000000000000F5FBF5ACFFFFFFFFFFFFFFFFFFFF2B002BF8F5ACFFFFFFFFFDF6FA000000000000F9FCFF560081
|
||||
FA0081FFFFF8F9000000000000FBF6FBFFFFFFFFFFFFFFFFFFFFFFF800F55600FCFFFFFFFFFF81F8F80000000000F981FFAC0081
|
||||
FA0000FEFEF8FB0000000000812BFAFFFFFFFFFFFFFEFFFFFDF92BFA0000F6F981ACFEFFFFFFFF56F9F600000000F9FDFF2B0081
|
||||
FA00FAFFFF81812B000000FAF8F9FFFFFEACFBF80000F500000000F9F900562B0000FCF7F9ACFFFF2BF9F50000F9F6FEFFFB0081
|
||||
810000FCFFFBF6FB56F7FBF8F9FFFE5600000000F5FAAC000000F82BF6FAFBF800F556F80000F9FFFE2BFAFAFAF8FAFFFEF60081
|
||||
FAF6F5ACFFFFAC00F856F7ACFFFCF500000000FAFCFFFC00000056AC00F581F92BFEF9FAF6000081FFFFFBF6F62BFFFFACF6F6FA
|
||||
F6FA00FAFFFFFFACFA56FFFFAC0000000000F6FD2BFEF6F5565600F5F800F60081FEF7F656000000FDFFFFFDFDFFFFFFAC0081F5
|
||||
0081F52BFDFFFFFFFFFFFFFFF60000000000FBF6F6F5F656F52BF900FA000000FCFAF5F656000000F7FFFFFFFFFFFFFDF7F68100
|
||||
00F6FB00F8FDFFFFFFFFFF810000000000F6F5000000F52B56F9FC00F7F70000FCF881FCF500000000FEFFFFFFFFAC5600FBF500
|
||||
000056F900F8ACFDFFFFFFF5000000000000002B0000FDFEFFFE560000F60000F9ACFFFE810000000081FFFEFDFAF800FAF70000
|
||||
000000FAF9002B56FAFDFC0000000000000000F80000FBF5FEFEF5000000000000ACFFFA2B0000000000FEFB2BF5008156000000
|
||||
00000000F9FBF600F6FBF800000000000000F7F8000000F9F9F9F82B0000000000F6ACACF70000000000F7FD2BFA812B00000000
|
||||
0000000000F681FCFBFD0000000000000000FBF6000000000000F52B000000000000F92B810000000000008181F6000000000000
|
||||
0000000000000000F6FC00000000000000F6FF0000000000000000000000000000000081FBFB2B00000000F7F900000000000000
|
||||
000000000000000000FC00000000000000FCFAF600000000000000000000000000000056ACF581FBF700000081FB000000000000
|
||||
0000000000000000FAF90000000000008156F5F8000000000000002BFBFCFBF800000000FD2B000056FB8181FBF8000000000000
|
||||
0000000000000000AC0000000000F5FBF90000F6000000000000F5AC56F6005681F50000F6ACFCFBF70000000000000000000000
|
||||
00000000000000F881000000F5FAFDFD00000000000000000000F7FEFA2B0000F581F70000000000810000000000000000000000
|
||||
000000000000F9FCF500FAFDACFAF5FD00000000000000000000F5ACF5FDFEFA0000F82B00000000810000000000000000000000
|
||||
000000000000FCF8F9AC81FD000000FD000000000000FAF7000000F50081F9FAF800000000000000FB0000000000000000000000
|
||||
000000000000FC81F956F5FD000000FD0000000000000000F800F5000000000056000000000000F7FB0000000000000000000000
|
||||
00000000000000000000F5AC000000ACF800000000000000F5FAF80000000000F50000000000F8ACF50000000000000000000000
|
||||
00000000000000000000F5AC000000F5AC000000000000000056F9000000000000000000F7ACFCF5000000000000000000000000
|
||||
00000000000000000000F5FD00000000AC000000000000000000FB0000000000000000F5F6F5FCF6000000000000000000000000
|
||||
0000000000000000000000FD00000000FBFDF600000000000000F8F900000000000000000000F5FB000000000000000000000000
|
||||
0000000000000000000000FDF500000000F9ACF800000000000000815600000000F656818181AC56000000000000000000000000
|
||||
000000000000000000000081F80000000000F9FC0000000000000000F9ACACACFCFBFAFA81FD2B00000000000000000000000000
|
||||
0000000000000000000000F7FB0000000000FBF70000000000000000000000000000000000FB0000000000000000000000000000
|
||||
000000000000000000000000ACF500000000F9FD56F5000000000000000000000000000000FB0000000000000000000000000000
|
||||
000000000000000000000000F8FA0000000000F6FEFEF5000000000000F55681FCACFDACFC560000000000000000000000000000
|
||||
00000000000000000000000000FBF600000000002BFCFA00F700000000F9FDFDFAFEF90000000000000000000000000000000000
|
||||
00000000000000000000000000F5FB0000000000F5FEF7ACAC0000000000000000FCF50000000000000000000000000000000000
|
||||
0000000000000000000000000000F6FA000000002BFF2BFFFFAC00000000000000F7FA0000000000000000000000000000000000
|
||||
000000000000000000000000000000F65600000000FAFEFFFFAC0000000000F800F6810000000000000000000000000000000000
|
||||
00000000000000000000000000000000F52B00000000F8FEFBFF5600000000FCFAACF60000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000F9FCFCFFFB00F8FEFFFDF5000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000F9FDF7F5FFFD56FFFFFFFD00000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000810000FBFFFFFBFFFFFFFFACF9F5F5000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000F600FC81FFFEFFFFFFFFFFFE8100000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000F7F6FDFFFFFFFEFFFFACF500000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000F5FC81FC81FAFBF9F500000000000000000000000000000000
|
||||
|
||||
00000000000000F781FB8181818181FBFAF500000000000000000000000000000000000000F6FAFAFAFA81F9F600000000000000
|
||||
0000000000F8FBF9F500F95656FCFB5656FBF800000000000000000000000000000000F5FAF9F5F7F600F6F6F9FAF70000000000
|
||||
000000F5FBFA0056FDFEFEFDFDFAAC81FB56568181560000000000000000000000F9F9F9F7FCFDFEFEFEFFFC81F656FA00000000
|
||||
0000F5AC2BF7FBFEFEFD2BF6568181F9F7F6F6F8FBF50000000000000000000000FAF700F600F5F7F7F6F7FEFFACF82BFB000000
|
||||
0000FC2BF5FEFFFFF5F7FC81F70000F7F9FAFAF8000000000000000000000000000056F9F9FAF9F7F7FA812BF7FFFF56F7FA0000
|
||||
005656F5FEFFAC2BF9FA000000000000000000000000000000000000000000000000000000000000000000FA56FAFEFEF8F9F700
|
||||
00FB00F7FFFF56F9F800000000000000000000F656FAFA56F50000000000F5F8F9F8F5000000000000000000F9F7FCFFFB00FB00
|
||||
F8F800ACFFACF6FA000000000000000000F6FA562BF5F5F781FA000000F9FA2B00F556F9F5000000000000000081F8FFFEF6562B
|
||||
810000FFFFF9FAF500000000000000002B8100F5F9FCACFBF82BFBF6FCFAF6FAFC81F600FA2B000000000000002BF8FEFFF8F5FA
|
||||
FA00F5FEFFFA8100000000000000002B8100F9FEFFFFFFFFFFFBF6FDFEACFDFEFFFFFFFBF581F600000000000000F9FEFFF700FA
|
||||
FA00FBFFFEF6F900000000000000F6FB00FCFFFFFFFFFFFFFFFFFCF600FCF7ACFEFFFFFFFDF6810000000000000056F9FFAC00FA
|
||||
FA00F6FFFFF856000000000000F5FBF5ACFFFFFFFFFFFFFFFFFFFF2B002BF8F5ACFFFFFFFFFDF6FA000000000000F9FCFF560081
|
||||
FA0081FFFFF8F9000000000000FBF6FBFFFFFFFFFFFFFFFFFFFFFFF800F55600FCFFFFFFFFFF81F8F80000000000F981FFAC0081
|
||||
FA0000FEFEF8FB0000000000812BFAFFFFFFFFFFFFFEFFFFFDF92BFA0000F6F981ACFEFFFFFFFF56F9F600000000F9FDFF2B0081
|
||||
FA00FAFFFF81812B000000FAF8F9FFFFFEACFBF80000F500000000F9F900562B0000FCF7F9ACFFFF2BF9F50000F9F6FEFFFB0081
|
||||
810000FCFFFBF6FB56F7FBF8F9FFFE5600000000F5FAAC000000F82BF6FAFBF800F556F80000F9FFFE2BFAFAFAF8FAFFFEF60081
|
||||
FAF6F5ACFFFFAC00F856F7ACFFFCF500000000FAFCFFFC00000056AC00F581F92BFEF9FAF6000081FFFFFBF6F62BFFFFACF6F6FA
|
||||
F6FA00FAFFFFFFACFA56FFFFAC0000000000F6FD2BFEF6F5565600F5F800F60081FEF7F656000000FDFFFFFDFDFFFFFFAC0081F5
|
||||
0081F52BFDFFFFFFFFFFFFFFF60000000000FBF6F6F5F656F52BF900FA000000FCFAF5F656000000F7FFFFFFFFFFFFFDF7F68100
|
||||
00F6FB00F8FDFFFFFFFFFF810000000000F6F5000000F52B56F9FC00F7F70000FCF881FCF500000000FEFFFFFFFFAC5600FBF500
|
||||
000056F900F8ACFDFFFFFFF5000000000000002B0000FDFEFFFE560000F60000F9ACFFFE810000000081FFFEFDFAF800FAF70000
|
||||
000000FAF9002B56FAFDFC0000000000000000F80000FBF5FEFEF5000000000000ACFFFA2B0000000000FEFB2BF5008156000000
|
||||
00000000F9FBF600F6FBF800000000000000F7F8000000F9F9F9F82B0000000000F6ACACF70000000000F7FD2BFA812B00000000
|
||||
0000000000F681FCFBFD0000000000000000FBF6000000000000F52B000000000000F92B810000000000008181F6000000000000
|
||||
0000000000000000F6FC00000000000000F6FF0000000000000000000000000000000081FBFB2B00000000F7F900000000000000
|
||||
000000000000000000FC00000000000000FCFAF600000000000000000000000000000056ACF581FBF700000081FB000000000000
|
||||
0000000000000000FAF90000000000008156F5F8000000000000002BFBFCFBF800000000FD2B000056FB8181FBF8000000000000
|
||||
0000000000000000AC0000000000F5FBF90000F6000000000000F5AC56F6005681F50000F6ACFCFBF70000000000000000000000
|
||||
00000000000000F881000000F5FAFDFD00000000000000000000F7FEFA2B0000F581F70000000000810000000000000000000000
|
||||
000000000000F9FCF500FAFDACFAF5FD00000000000000000000F5ACF5FDFEFA0000F82B00000000810000000000000000000000
|
||||
000000000000FCF8F9AC81FD000000FD000000000000FAF7000000F50081F9FAF800000000000000FB0000000000000000000000
|
||||
000000000000FC81F956F5FD000000FD0000000000000000F800F5000000000056000000000000F7FB0000000000000000000000
|
||||
00000000000000000000F5AC000000ACF800000000000000F5FAF80000000000F50000000000F8ACF50000000000000000000000
|
||||
00000000000000000000F5AC000000F5AC000000000000000056F9000000000000000000F7ACFCF5000000000000000000000000
|
||||
00000000000000000000F5FD00000000AC000000000000000000FB0000000000000000F5F6F5FCF6000000000000000000000000
|
||||
0000000000000000000000FD00000000FBFDF600000000000000F8F900000000000000000000F5FB000000000000000000000000
|
||||
0000000000000000000000FDF500000000F9ACF800000000000000815600000000F656818181AC56000000000000000000000000
|
||||
000000000000000000000081F80000000000F9FC0000000000000000F9ACACACFCFBFAFA81FD2B00000000000000000000000000
|
||||
0000000000000000000000F7FB0000000000FBF70000000000000000000000000000000000FB0000000000000000000000000000
|
||||
000000000000000000000000ACF500000000F9FD56F5000000000000000000000000000000FB0000000000000000000000000000
|
||||
000000000000000000000000F8FA0000000000F6FEFEF5000000000000F55681FCACFDACFC560000000000000000000000000000
|
||||
00000000000000000000000000FBF600000000002BFCFA00F700000000F9FDFDFAFEF90000000000000000000000000000000000
|
||||
00000000000000000000000000F5FB0000000000F5FEF7ACAC0000000000000000FCF50000000000000000000000000000000000
|
||||
0000000000000000000000000000F6FA000000002BFF2BFFFFAC00000000000000F7FA0000000000000000000000000000000000
|
||||
000000000000000000000000000000F65600000000FAFEFFFFAC0000000000F800F6810000000000000000000000000000000000
|
||||
00000000000000000000000000000000F52B00000000F8FEFBFF5600000000FCFAACF60000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000F9FCFCFFFB00F8FEFFFDF5000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000F9FDF7F5FFFD56FFFFFFFD00000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000810000FBFFFFFBFFFFFFFFACF9F5F5000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000F600FC81FFFEFFFFFFFFFFFE8100000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000F7F6FDFFFFFFFEFFFFACF500000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000F5FC81FC81FAFBF9F500000000000000000000000000000000
|
||||
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
</OS-BADGE-ICONS>
|
||||
<BOOT-SCRIPT>
|
||||
boot &device;:&partition;,\System\Library\CoreServices\VasEBoot.elf
|
||||
</BOOT-SCRIPT>
|
||||
</CHRP-BOOT>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<chrp-boot>
|
||||
<description>@PACKAGE@ @VERSION@</description>
|
||||
<os-name>@PACKAGE@ @VERSION@</os-name>
|
||||
<boot-script>boot &device;:\boot\grub\powerpc.elf</boot-script>
|
||||
<boot-script>boot &device;:\boot\VasEBoot\powerpc.elf</boot-script>
|
||||
<icon size=64,64 color-space=3,3,2>
|
||||
<bitmap>
|
||||
FF FF FF FF FF FF FF FF FF FF 92 6D 6D 6D 6D 6D 6D 6D 6D 6D DB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF B6 92 6D 92 92 92 DB FF FF FF FF FF FF FF FF FF FF
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
/* -*-Asm-*- */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
|
||||
.text
|
||||
.align 4
|
||||
/*
|
||||
* We're writing the a.out header ourselves as newer
|
||||
* upstream versions of binutils no longer support
|
||||
* the a.out format on sparc64.
|
||||
*
|
||||
* The boot loader fits into 512 bytes with 32 bytes
|
||||
* used for the a.out header, hence the text segment
|
||||
* size is 512 - 32. There is no data segment and no
|
||||
* code relocation, thus those fields remain zero.
|
||||
*/
|
||||
.word 0x1030107 /* Magic number. */
|
||||
.word 512 - VAS_EBOOT_BOOT_AOUT_HEADER_SIZE /* Size of text segment. */
|
||||
.word 0 /* Size of initialized data. */
|
||||
.word 0 /* Size of uninitialized data. */
|
||||
.word 0 /* Size of symbol table || checksum. */
|
||||
.word _start /* Entry point. */
|
||||
.word 0 /* Size of text relocation. */
|
||||
.word 0 /* Size of data relocation. */
|
||||
.globl _start
|
||||
_start:
|
||||
/* OF CIF entry point arrives in %o4 */
|
||||
pic_base:
|
||||
call boot_continue
|
||||
mov %o4, CIF_REG
|
||||
|
||||
#ifndef CDBOOT
|
||||
/* The offsets to these locations are defined by the
|
||||
* VAS_EBOOT_BOOT_MACHINE_foo macros in include/VasEBoot/sparc64/ieee1275/boot.h,
|
||||
* and VasEBoot-setup uses this to patch these next three values as needed.
|
||||
*
|
||||
* The boot_path will be the OF device path of the partition where the
|
||||
* rest of the VAS_EBOOT kernel image resides. kernel_sector will be set to
|
||||
* the location of the first block of the VAS_EBOOT kernel, and
|
||||
* kernel_address is the location where we should load that first block.
|
||||
*
|
||||
* After loading in that block we will execute it by jumping to the
|
||||
* load address plus the size of the prepended A.OUT header (32 bytes).
|
||||
*
|
||||
* Since this assembly code includes the 32 bytes long a.out header,
|
||||
* we need to move the actual code entry point forward by the size
|
||||
* of the a.out header, i.e. += VAS_EBOOT_BOOT_AOUT_HEADER_SIZE.
|
||||
*/
|
||||
.org VAS_EBOOT_BOOT_MACHINE_BOOT_DEVPATH + VAS_EBOOT_BOOT_AOUT_HEADER_SIZE
|
||||
boot_path:
|
||||
.org VAS_EBOOT_BOOT_MACHINE_KERNEL_BYTE + VAS_EBOOT_BOOT_AOUT_HEADER_SIZE
|
||||
boot_path_end:
|
||||
kernel_byte: .xword (2 << 9)
|
||||
kernel_address: .word VAS_EBOOT_BOOT_MACHINE_KERNEL_ADDR
|
||||
#else
|
||||
#define boot_path (_start + 512 + SCRATCH_PAD_BOOT_SIZE)
|
||||
#define boot_path_end (_start + 1024)
|
||||
#include <VasEBoot/offsets.h>
|
||||
|
||||
.org 8 + VAS_EBOOT_BOOT_AOUT_HEADER_SIZE
|
||||
kernel_byte: .xword (2 << 9)
|
||||
kernel_size: .word 512
|
||||
kernel_address: .word VAS_EBOOT_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS
|
||||
#endif
|
||||
|
||||
prom_finddev_name: .asciz "finddevice"
|
||||
prom_chosen_path: .asciz "/chosen"
|
||||
prom_getprop_name: .asciz "getprop"
|
||||
prom_stdout_name: .asciz "stdout"
|
||||
prom_write_name: .asciz "write"
|
||||
prom_bootpath_name: .asciz "bootpath"
|
||||
prom_open_name: .asciz "open"
|
||||
prom_seek_name: .asciz "seek"
|
||||
prom_read_name: .asciz "read"
|
||||
prom_exit_name: .asciz "exit"
|
||||
VasEBoot_name: .asciz "VAS_EBOOT "
|
||||
#ifdef CDBOOT
|
||||
prom_close_name: .asciz "close"
|
||||
#endif
|
||||
|
||||
#define VAS_EBOOT_NAME_LEN 5
|
||||
|
||||
.align 4
|
||||
|
||||
prom_open_error:
|
||||
GET_ABS(prom_open_name, %o2)
|
||||
call console_write
|
||||
mov 4, %o3
|
||||
/* fallthru */
|
||||
|
||||
prom_error:
|
||||
GET_ABS(prom_exit_name, %o0)
|
||||
/* fallthru */
|
||||
|
||||
/* %o0: OF call name
|
||||
* %o1: input arg 1
|
||||
*/
|
||||
prom_call_1_1_o2:
|
||||
clr %o2
|
||||
ba prom_call_x_1
|
||||
mov 1, %g1
|
||||
|
||||
prom_call_getprop:
|
||||
mov 4, %g1
|
||||
stx %g1, [%l1 + 256]
|
||||
mov CHOSEN_NODE_REG, %o1
|
||||
ba prom_call_x_1
|
||||
GET_ABS(prom_getprop_name, %o0)
|
||||
|
||||
prom_call_3_1_o1:
|
||||
ba prom_call_3_1
|
||||
mov BOOTDEV_REG, %o1
|
||||
|
||||
|
||||
/* %o2: message string
|
||||
* %o3: message length
|
||||
*/
|
||||
console_write:
|
||||
GET_ABS(prom_write_name, %o0)
|
||||
mov STDOUT_NODE_REG, %o1
|
||||
/* fallthru */
|
||||
|
||||
/* %o0: OF call name
|
||||
* %o1: input arg 1
|
||||
* %o2: input arg 2
|
||||
* %o3: input arg 3
|
||||
*/
|
||||
prom_call_3_1:
|
||||
mov 3, %g1
|
||||
prom_call_x_1:
|
||||
mov 1, %o5
|
||||
/* fallthru */
|
||||
|
||||
/* %o0: OF call name
|
||||
* %g1: num inputs
|
||||
* %o5: num outputs
|
||||
* %o1-%o4: inputs
|
||||
*/
|
||||
prom_call:
|
||||
stx %o0, [%l1 + 0x00]
|
||||
stx %g1, [%l1 + 0x08]
|
||||
stx %o5, [%l1 + 0x10]
|
||||
stx %o1, [%l1 + 0x18]
|
||||
stx %o2, [%l1 + 0x20]
|
||||
stx %o3, [%l1 + 0x28]
|
||||
stx %o4, [%l1 + 0x30]
|
||||
jmpl CIF_REG, %g0
|
||||
mov %l1, %o0
|
||||
|
||||
boot_continue:
|
||||
mov %o7, PIC_REG /* PIC base */
|
||||
#ifndef CDBOOT
|
||||
sethi %hi(SCRATCH_PAD_BOOT), %l1 /* OF argument slots */
|
||||
#else
|
||||
GET_ABS(_start + 512, %l1) /* OF argument slots */
|
||||
#endif
|
||||
|
||||
/* Find the /chosen node so we can fetch the stdout handle,
|
||||
* and thus perform console output.
|
||||
*
|
||||
* chosen_node = prom_finddevice("/chosen")
|
||||
*/
|
||||
GET_ABS(prom_finddev_name, %o0)
|
||||
call prom_call_1_1_o2
|
||||
GET_ABS(prom_chosen_path, %o1)
|
||||
|
||||
ldx [%l1 + 0x20], CHOSEN_NODE_REG
|
||||
brz CHOSEN_NODE_REG, prom_error
|
||||
|
||||
/* getprop(chosen_node, "stdout", &buffer, buffer_size) */
|
||||
GET_ABS(prom_stdout_name, %o2)
|
||||
add %l1, 256, %o3
|
||||
call prom_call_getprop
|
||||
mov 1024, %o4
|
||||
|
||||
lduw [%l1 + 256], STDOUT_NODE_REG
|
||||
brz,pn STDOUT_NODE_REG, prom_error
|
||||
|
||||
/* write(stdout_node, "VAS_EBOOT ", strlen("VAS_EBOOT ")) */
|
||||
GET_ABS(VasEBoot_name, %o2)
|
||||
call console_write
|
||||
mov VAS_EBOOT_NAME_LEN, %o3
|
||||
|
||||
GET_ABS(boot_path, %o3)
|
||||
#ifndef CDBOOT
|
||||
ldub [%o3], %o1
|
||||
brnz,pn %o1, bootpath_known
|
||||
#endif
|
||||
|
||||
/* getprop(chosen_node, "bootpath", &buffer, buffer_size) */
|
||||
GET_ABS(prom_bootpath_name, %o2)
|
||||
call prom_call_getprop
|
||||
mov (boot_path_end - boot_path), %o4
|
||||
|
||||
bootpath_known:
|
||||
|
||||
/* Open up the boot_path, and use that handle to read the
|
||||
* first block of the VAS_EBOOT kernel image.
|
||||
*
|
||||
* bootdev_handle = open(boot_path)
|
||||
*/
|
||||
GET_ABS(prom_open_name, %o0)
|
||||
call prom_call_1_1_o2
|
||||
GET_ABS(boot_path, %o1)
|
||||
|
||||
ldx [%l1 + 0x20], BOOTDEV_REG
|
||||
brz,pn BOOTDEV_REG, prom_open_error
|
||||
|
||||
/* Since we have 64-bit cells, the high cell of the seek offset
|
||||
* is zero and the low cell is the entire value.
|
||||
*
|
||||
* seek(bootdev, 0, *kernel_byte)
|
||||
*/
|
||||
GET_ABS(prom_seek_name, %o0)
|
||||
clr %o2
|
||||
call prom_call_3_1_o1
|
||||
LDX_ABS(kernel_byte, 0x00, %o3)
|
||||
|
||||
/* read(bootdev, *kernel_address, 512) */
|
||||
GET_ABS(prom_read_name, %o0)
|
||||
LDUW_ABS(kernel_address, 0x00, %o2)
|
||||
call prom_call_3_1_o1
|
||||
#ifdef CDBOOT
|
||||
LDUW_ABS(kernel_size, 0x00, %o3)
|
||||
|
||||
GET_ABS(prom_close_name, %o0)
|
||||
mov 1, %g1
|
||||
mov 0, %o5
|
||||
call prom_call
|
||||
mov BOOTDEV_REG, %o1
|
||||
#else
|
||||
mov 512, %o3
|
||||
#endif
|
||||
|
||||
LDUW_ABS(kernel_address, 0x00, %o2)
|
||||
jmpl %o2, %o7
|
||||
#ifdef CDBOOT
|
||||
mov CIF_REG, %o4
|
||||
#else
|
||||
nop
|
||||
#endif
|
||||
.org VAS_EBOOT_BOOT_MACHINE_CODE_END
|
||||
|
||||
/* the last 4 bytes in the sector 0 contain the signature */
|
||||
.word VAS_EBOOT_BOOT_MACHINE_SIGNATURE
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/* -*-Asm-*- */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/machine/boot.h>
|
||||
#include <VasEBoot/offsets.h>
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.globl _start
|
||||
_start:
|
||||
/* First stage boot block jumps to us here. */
|
||||
pic_base:
|
||||
call after_info_block
|
||||
mov %o7, PIC_REG
|
||||
|
||||
prom_write_name: .asciz "write"
|
||||
prom_seek_name: .asciz "seek"
|
||||
prom_read_name: .asciz "read"
|
||||
prom_close_name: .asciz "close"
|
||||
|
||||
notification_string: .asciz "Loading kernel"
|
||||
#define NOTIFICATION_STRING_LEN 14
|
||||
|
||||
notification_step: .asciz "."
|
||||
#define NOTIFICATION_STEP_LEN 1
|
||||
|
||||
notification_done: .asciz "\r\n"
|
||||
#define NOTIFICATION_DONE_LEN 2
|
||||
|
||||
.align 4
|
||||
|
||||
/* %o2: message string
|
||||
* %o3: message length
|
||||
*/
|
||||
console_write:
|
||||
GET_ABS(prom_write_name, %o0)
|
||||
mov STDOUT_NODE_REG, %o1
|
||||
/* fallthru */
|
||||
|
||||
/* %o0: OF call name
|
||||
* %o1: input arg 1
|
||||
* %o2: input arg 2
|
||||
* %o3: input arg 3
|
||||
*/
|
||||
prom_call_3_1:
|
||||
mov 3, %g1
|
||||
mov 1, %o5
|
||||
/* fallthru */
|
||||
|
||||
/* %o0: OF call name
|
||||
* %g1: num inputs
|
||||
* %o5: num outputs
|
||||
* %o1-%o4: inputs
|
||||
*/
|
||||
prom_call:
|
||||
stx %o0, [%l1 + 0x00]
|
||||
stx %g1, [%l1 + 0x08]
|
||||
stx %o5, [%l1 + 0x10]
|
||||
stx %o1, [%l1 + 0x18]
|
||||
stx %o2, [%l1 + 0x20]
|
||||
stx %o3, [%l1 + 0x28]
|
||||
stx %o4, [%l1 + 0x30]
|
||||
jmpl CIF_REG, %g0
|
||||
mov %l1, %o0
|
||||
|
||||
|
||||
after_info_block:
|
||||
sethi %hi(SCRATCH_PAD_DISKBOOT), %l1 /* OF argument slots */
|
||||
|
||||
GET_ABS(notification_string, %o2)
|
||||
call console_write
|
||||
mov NOTIFICATION_STRING_LEN, %o3
|
||||
|
||||
GET_ABS(firstlist - VAS_EBOOT_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2)
|
||||
set VAS_EBOOT_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS, %l3
|
||||
bootloop:
|
||||
lduw [%l2 + 0x08], %o0
|
||||
brz %o0, bootit
|
||||
lduw [%l2 + 0x00], %o3
|
||||
sllx %o3, 32, %o3
|
||||
lduw [%l2 + 0x04], %o4
|
||||
or %o3, %o4, %o3
|
||||
GET_ABS(prom_seek_name, %o0)
|
||||
mov BOOTDEV_REG, %o1
|
||||
clr %o2
|
||||
call prom_call_3_1
|
||||
sllx %o3, 9, %o3
|
||||
|
||||
GET_ABS(prom_read_name, %o0)
|
||||
mov BOOTDEV_REG, %o1
|
||||
lduw [%l2 + 0x08], %o3
|
||||
sllx %o3, 9, %o3
|
||||
mov %l3, %o2
|
||||
call prom_call_3_1
|
||||
add %l3, %o3, %l3
|
||||
|
||||
GET_ABS(notification_step, %o2)
|
||||
call console_write
|
||||
mov NOTIFICATION_STEP_LEN, %o3
|
||||
|
||||
ba bootloop
|
||||
sub %l2, VAS_EBOOT_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2
|
||||
|
||||
bootit:
|
||||
GET_ABS(prom_close_name, %o0)
|
||||
mov 1, %g1
|
||||
mov 0, %o5
|
||||
call prom_call
|
||||
mov BOOTDEV_REG, %o1
|
||||
|
||||
GET_ABS(notification_done, %o2)
|
||||
call console_write
|
||||
mov NOTIFICATION_DONE_LEN, %o3
|
||||
sethi %hi(VAS_EBOOT_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o2
|
||||
jmpl %o2 + %lo(VAS_EBOOT_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o7
|
||||
mov CIF_REG, %o4
|
||||
1: ba,a 1b
|
||||
|
||||
lastlist:
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
.org (0x200 - VAS_EBOOT_BOOT_SPARC64_IEEE1275_LIST_SIZE)
|
||||
blocklist_default_start:
|
||||
.word 0
|
||||
.word 2
|
||||
blocklist_default_len:
|
||||
.word 0
|
||||
firstlist:
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
/* bonito.c - PCI bonito interface. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
|
||||
static VasEBoot_uint32_t base_win[VAS_EBOOT_MACHINE_PCI_NUM_WIN];
|
||||
static const VasEBoot_size_t sizes_win[VAS_EBOOT_MACHINE_PCI_NUM_WIN] =
|
||||
{VAS_EBOOT_MACHINE_PCI_WIN1_SIZE, VAS_EBOOT_MACHINE_PCI_WIN_SIZE,
|
||||
VAS_EBOOT_MACHINE_PCI_WIN_SIZE};
|
||||
/* Usage counters. */
|
||||
static int usage_win[VAS_EBOOT_MACHINE_PCI_NUM_WIN];
|
||||
static VasEBoot_addr_t addr_win[VAS_EBOOT_MACHINE_PCI_NUM_WIN] =
|
||||
{VAS_EBOOT_MACHINE_PCI_WIN1_ADDR, VAS_EBOOT_MACHINE_PCI_WIN2_ADDR,
|
||||
VAS_EBOOT_MACHINE_PCI_WIN3_ADDR};
|
||||
|
||||
VasEBoot_bonito_type_t VasEBoot_bonito_type;
|
||||
|
||||
static volatile void *
|
||||
config_addr (VasEBoot_pci_address_t addr)
|
||||
{
|
||||
if (VasEBoot_bonito_type == VAS_EBOOT_BONITO_2F)
|
||||
{
|
||||
VAS_EBOOT_MACHINE_PCI_CONF_CTRL_REG_2F = 1 << ((addr >> 11) & 0xf);
|
||||
return (volatile void *) (VAS_EBOOT_MACHINE_PCI_CONFSPACE_2F
|
||||
| (addr & 0x07ff));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (addr >> 16)
|
||||
return (volatile void *) (VAS_EBOOT_MACHINE_PCI_CONFSPACE_3A_EXT | addr);
|
||||
else
|
||||
return (volatile void *) (VAS_EBOOT_MACHINE_PCI_CONFSPACE_3A | addr);
|
||||
}
|
||||
}
|
||||
|
||||
VasEBoot_uint32_t
|
||||
VasEBoot_pci_read (VasEBoot_pci_address_t addr)
|
||||
{
|
||||
return *(volatile VasEBoot_uint32_t *) config_addr (addr);
|
||||
}
|
||||
|
||||
VasEBoot_uint16_t
|
||||
VasEBoot_pci_read_word (VasEBoot_pci_address_t addr)
|
||||
{
|
||||
return *(volatile VasEBoot_uint16_t *) config_addr (addr);
|
||||
}
|
||||
|
||||
VasEBoot_uint8_t
|
||||
VasEBoot_pci_read_byte (VasEBoot_pci_address_t addr)
|
||||
{
|
||||
return *(volatile VasEBoot_uint8_t *) config_addr (addr);
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_pci_write (VasEBoot_pci_address_t addr, VasEBoot_uint32_t data)
|
||||
{
|
||||
*(volatile VasEBoot_uint32_t *) config_addr (addr) = data;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_pci_write_word (VasEBoot_pci_address_t addr, VasEBoot_uint16_t data)
|
||||
{
|
||||
*(volatile VasEBoot_uint16_t *) config_addr (addr) = data;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_pci_write_byte (VasEBoot_pci_address_t addr, VasEBoot_uint8_t data)
|
||||
{
|
||||
*(volatile VasEBoot_uint8_t *) config_addr (addr) = data;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
write_bases_2f (void)
|
||||
{
|
||||
int i;
|
||||
VasEBoot_uint32_t reg = 0;
|
||||
for (i = 0; i < VAS_EBOOT_MACHINE_PCI_NUM_WIN; i++)
|
||||
reg |= (((base_win[i] >> VAS_EBOOT_MACHINE_PCI_WIN_SHIFT)
|
||||
& VAS_EBOOT_MACHINE_PCI_WIN_MASK)
|
||||
<< (i * VAS_EBOOT_MACHINE_PCI_WIN_MASK_SIZE));
|
||||
VAS_EBOOT_MACHINE_PCI_IO_CTRL_REG_2F = reg;
|
||||
}
|
||||
|
||||
volatile void *
|
||||
VasEBoot_pci_device_map_range (VasEBoot_pci_device_t dev __attribute__ ((unused)),
|
||||
VasEBoot_addr_t base, VasEBoot_size_t size)
|
||||
{
|
||||
if (VasEBoot_bonito_type == VAS_EBOOT_BONITO_2F)
|
||||
{
|
||||
int i;
|
||||
VasEBoot_addr_t newbase;
|
||||
|
||||
/* First try already used registers. */
|
||||
for (i = 0; i < VAS_EBOOT_MACHINE_PCI_NUM_WIN; i++)
|
||||
if (usage_win[i] && base_win[i] <= base
|
||||
&& base_win[i] + sizes_win[i] > base + size)
|
||||
{
|
||||
usage_win[i]++;
|
||||
return (void *)
|
||||
(addr_win[i] | (base & VAS_EBOOT_MACHINE_PCI_WIN_OFFSET_MASK));
|
||||
}
|
||||
/* Map new register. */
|
||||
newbase = base & ~VAS_EBOOT_MACHINE_PCI_WIN_OFFSET_MASK;
|
||||
for (i = 0; i < VAS_EBOOT_MACHINE_PCI_NUM_WIN; i++)
|
||||
if (!usage_win[i] && newbase <= base
|
||||
&& newbase + sizes_win[i] > base + size)
|
||||
{
|
||||
usage_win[i]++;
|
||||
base_win[i] = newbase;
|
||||
write_bases_2f ();
|
||||
return (void *)
|
||||
(addr_win[i] | (base & VAS_EBOOT_MACHINE_PCI_WIN_OFFSET_MASK));
|
||||
}
|
||||
VasEBoot_fatal ("Out of PCI windows.");
|
||||
}
|
||||
else
|
||||
{
|
||||
int region = 0;
|
||||
if (base >= 0x10000000
|
||||
&& base + size <= 0x18000000)
|
||||
region = 1;
|
||||
if (base >= 0x1c000000
|
||||
&& base + size <= 0x1f000000)
|
||||
region = 2;
|
||||
if (region == 0)
|
||||
VasEBoot_fatal ("Attempt to map out of regions");
|
||||
return (void *) (0xa0000000 | base);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
VasEBoot_pci_device_map_range_cached (VasEBoot_pci_device_t dev,
|
||||
VasEBoot_addr_t base, VasEBoot_size_t size)
|
||||
{
|
||||
return (void *) (((VasEBoot_addr_t) VasEBoot_pci_device_map_range (dev, base, size))
|
||||
& ~0x20000000);
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_pci_device_unmap_range (VasEBoot_pci_device_t dev __attribute__ ((unused)),
|
||||
volatile void *mem,
|
||||
VasEBoot_size_t size __attribute__ ((unused)))
|
||||
{
|
||||
if (VasEBoot_bonito_type == VAS_EBOOT_BONITO_2F)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < VAS_EBOOT_MACHINE_PCI_NUM_WIN; i++)
|
||||
if (usage_win[i] && addr_win[i]
|
||||
== (((VasEBoot_addr_t) mem | 0x20000000)
|
||||
& ~VAS_EBOOT_MACHINE_PCI_WIN_OFFSET_MASK))
|
||||
{
|
||||
usage_win[i]--;
|
||||
return;
|
||||
}
|
||||
VasEBoot_fatal ("Tried to unmap not mapped region");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/cs5536.h>
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/time.h>
|
||||
#include <VasEBoot/ata.h>
|
||||
#ifdef VAS_EBOOT_MACHINE_MIPS_LOONGSON
|
||||
#include <VasEBoot/machine/kernel.h>
|
||||
#endif
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Context for VasEBoot_cs5536_find. */
|
||||
struct VasEBoot_cs5536_find_ctx
|
||||
{
|
||||
VasEBoot_pci_device_t *devp;
|
||||
int found;
|
||||
};
|
||||
|
||||
/* Helper for VasEBoot_cs5536_find. */
|
||||
static int
|
||||
VasEBoot_cs5536_find_iter (VasEBoot_pci_device_t dev, VasEBoot_pci_id_t pciid, void *data)
|
||||
{
|
||||
struct VasEBoot_cs5536_find_ctx *ctx = data;
|
||||
|
||||
if (pciid == VAS_EBOOT_CS5536_PCIID)
|
||||
{
|
||||
*ctx->devp = dev;
|
||||
ctx->found = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
VasEBoot_cs5536_find (VasEBoot_pci_device_t *devp)
|
||||
{
|
||||
struct VasEBoot_cs5536_find_ctx ctx = {
|
||||
.devp = devp,
|
||||
.found = 0
|
||||
};
|
||||
|
||||
VasEBoot_pci_iterate (VasEBoot_cs5536_find_iter, &ctx);
|
||||
|
||||
return ctx.found;
|
||||
}
|
||||
|
||||
VasEBoot_uint64_t
|
||||
VasEBoot_cs5536_read_msr (VasEBoot_pci_device_t dev, VasEBoot_uint32_t addr)
|
||||
{
|
||||
VasEBoot_uint64_t ret = 0;
|
||||
VasEBoot_pci_write (VasEBoot_pci_make_address (dev, VAS_EBOOT_CS5536_MSR_MAILBOX_ADDR),
|
||||
addr);
|
||||
ret = (VasEBoot_uint64_t)
|
||||
VasEBoot_pci_read (VasEBoot_pci_make_address (dev, VAS_EBOOT_CS5536_MSR_MAILBOX_DATA0));
|
||||
ret |= (((VasEBoot_uint64_t)
|
||||
VasEBoot_pci_read (VasEBoot_pci_make_address (dev,
|
||||
VAS_EBOOT_CS5536_MSR_MAILBOX_DATA1)))
|
||||
<< 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_cs5536_write_msr (VasEBoot_pci_device_t dev, VasEBoot_uint32_t addr,
|
||||
VasEBoot_uint64_t val)
|
||||
{
|
||||
VasEBoot_pci_write (VasEBoot_pci_make_address (dev, VAS_EBOOT_CS5536_MSR_MAILBOX_ADDR),
|
||||
addr);
|
||||
VasEBoot_pci_write (VasEBoot_pci_make_address (dev, VAS_EBOOT_CS5536_MSR_MAILBOX_DATA0),
|
||||
val & 0xffffffff);
|
||||
VasEBoot_pci_write (VasEBoot_pci_make_address (dev, VAS_EBOOT_CS5536_MSR_MAILBOX_DATA1),
|
||||
val >> 32);
|
||||
}
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_cs5536_smbus_wait (VasEBoot_port_t smbbase)
|
||||
{
|
||||
VasEBoot_uint64_t start = VasEBoot_get_time_ms ();
|
||||
while (1)
|
||||
{
|
||||
VasEBoot_uint8_t status;
|
||||
status = VasEBoot_inb (smbbase + VAS_EBOOT_CS5536_SMB_REG_STATUS);
|
||||
if (status & VAS_EBOOT_CS5536_SMB_REG_STATUS_SDAST)
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
if (status & VAS_EBOOT_CS5536_SMB_REG_STATUS_BER)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_IO, "SM bus error");
|
||||
if (status & VAS_EBOOT_CS5536_SMB_REG_STATUS_NACK)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_IO, "NACK received");
|
||||
if (VasEBoot_get_time_ms () > start + 40)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_IO, "SM stalled");
|
||||
}
|
||||
}
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_cs5536_read_spd_byte (VasEBoot_port_t smbbase, VasEBoot_uint8_t dev,
|
||||
VasEBoot_uint8_t addr, VasEBoot_uint8_t *res)
|
||||
{
|
||||
VasEBoot_err_t err;
|
||||
|
||||
/* Send START. */
|
||||
VasEBoot_outb (VasEBoot_inb (smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1)
|
||||
| VAS_EBOOT_CS5536_SMB_REG_CTRL1_START,
|
||||
smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1);
|
||||
|
||||
/* Send device address. */
|
||||
err = VasEBoot_cs5536_smbus_wait (smbbase);
|
||||
if (err)
|
||||
return err;
|
||||
VasEBoot_outb (dev << 1, smbbase + VAS_EBOOT_CS5536_SMB_REG_DATA);
|
||||
|
||||
/* Send ACK. */
|
||||
err = VasEBoot_cs5536_smbus_wait (smbbase);
|
||||
if (err)
|
||||
return err;
|
||||
VasEBoot_outb (VasEBoot_inb (smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1)
|
||||
| VAS_EBOOT_CS5536_SMB_REG_CTRL1_ACK,
|
||||
smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1);
|
||||
|
||||
/* Send byte address. */
|
||||
VasEBoot_outb (addr, smbbase + VAS_EBOOT_CS5536_SMB_REG_DATA);
|
||||
|
||||
/* Send START. */
|
||||
err = VasEBoot_cs5536_smbus_wait (smbbase);
|
||||
if (err)
|
||||
return err;
|
||||
VasEBoot_outb (VasEBoot_inb (smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1)
|
||||
| VAS_EBOOT_CS5536_SMB_REG_CTRL1_START,
|
||||
smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1);
|
||||
|
||||
/* Send device address. */
|
||||
err = VasEBoot_cs5536_smbus_wait (smbbase);
|
||||
if (err)
|
||||
return err;
|
||||
VasEBoot_outb ((dev << 1) | 1, smbbase + VAS_EBOOT_CS5536_SMB_REG_DATA);
|
||||
|
||||
/* Send STOP. */
|
||||
err = VasEBoot_cs5536_smbus_wait (smbbase);
|
||||
if (err)
|
||||
return err;
|
||||
VasEBoot_outb (VasEBoot_inb (smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1)
|
||||
| VAS_EBOOT_CS5536_SMB_REG_CTRL1_STOP,
|
||||
smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1);
|
||||
|
||||
err = VasEBoot_cs5536_smbus_wait (smbbase);
|
||||
if (err)
|
||||
return err;
|
||||
*res = VasEBoot_inb (smbbase + VAS_EBOOT_CS5536_SMB_REG_DATA);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_cs5536_init_smbus (VasEBoot_pci_device_t dev, VasEBoot_uint16_t divisor,
|
||||
VasEBoot_port_t *smbbase)
|
||||
{
|
||||
VasEBoot_uint64_t smbbar;
|
||||
|
||||
smbbar = VasEBoot_cs5536_read_msr (dev, VAS_EBOOT_CS5536_MSR_SMB_BAR);
|
||||
|
||||
/* FIXME */
|
||||
if (!(smbbar & VAS_EBOOT_CS5536_LBAR_ENABLE))
|
||||
return VasEBoot_error(VAS_EBOOT_ERR_IO, "SMB controller not enabled\n");
|
||||
*smbbase = (smbbar & VAS_EBOOT_CS5536_LBAR_ADDR_MASK) + VAS_EBOOT_MACHINE_PCI_IO_BASE;
|
||||
|
||||
if (divisor < 8)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "invalid divisor");
|
||||
|
||||
/* Disable SMB. */
|
||||
VasEBoot_outb (0, *smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL2);
|
||||
|
||||
/* Disable interrupts. */
|
||||
VasEBoot_outb (0, *smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL1);
|
||||
|
||||
/* Set as master. */
|
||||
VasEBoot_outb (VAS_EBOOT_CS5536_SMB_REG_ADDR_MASTER,
|
||||
*smbbase + VAS_EBOOT_CS5536_SMB_REG_ADDR);
|
||||
|
||||
/* Launch. */
|
||||
VasEBoot_outb (((divisor >> 7) & 0xff), *smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL3);
|
||||
VasEBoot_outb (((divisor << 1) & 0xfe) | VAS_EBOOT_CS5536_SMB_REG_CTRL2_ENABLE,
|
||||
*smbbase + VAS_EBOOT_CS5536_SMB_REG_CTRL2);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_cs5536_read_spd (VasEBoot_port_t smbbase, VasEBoot_uint8_t dev,
|
||||
struct VasEBoot_smbus_spd *res)
|
||||
{
|
||||
VasEBoot_err_t err;
|
||||
VasEBoot_size_t size;
|
||||
VasEBoot_uint8_t b;
|
||||
VasEBoot_size_t ptr;
|
||||
|
||||
err = VasEBoot_cs5536_read_spd_byte (smbbase, dev, 0, &b);
|
||||
if (err)
|
||||
return err;
|
||||
if (b == 0)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_IO, "no SPD found");
|
||||
size = b;
|
||||
|
||||
((VasEBoot_uint8_t *) res)[0] = b;
|
||||
for (ptr = 1; ptr < size; ptr++)
|
||||
{
|
||||
err = VasEBoot_cs5536_read_spd_byte (smbbase, dev, ptr,
|
||||
&((VasEBoot_uint8_t *) res)[ptr]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_io_space (VasEBoot_pci_device_t dev, int num, VasEBoot_uint16_t start,
|
||||
VasEBoot_uint16_t len)
|
||||
{
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_GL_REGIONS_START + num,
|
||||
((((VasEBoot_uint64_t) start + len - 4)
|
||||
<< VAS_EBOOT_CS5536_MSR_GL_REGION_IO_TOP_SHIFT)
|
||||
& VAS_EBOOT_CS5536_MSR_GL_REGION_TOP_MASK)
|
||||
| (((VasEBoot_uint64_t) start
|
||||
<< VAS_EBOOT_CS5536_MSR_GL_REGION_IO_BASE_SHIFT)
|
||||
& VAS_EBOOT_CS5536_MSR_GL_REGION_BASE_MASK)
|
||||
| VAS_EBOOT_CS5536_MSR_GL_REGION_IO
|
||||
| VAS_EBOOT_CS5536_MSR_GL_REGION_ENABLE);
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_iod (VasEBoot_pci_device_t dev, int num, int dest, int start, int mask)
|
||||
{
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_GL_IOD_START + num,
|
||||
((VasEBoot_uint64_t) dest << VAS_EBOOT_CS5536_IOD_DEST_SHIFT)
|
||||
| (((VasEBoot_uint64_t) start & VAS_EBOOT_CS5536_IOD_ADDR_MASK)
|
||||
<< VAS_EBOOT_CS5536_IOD_BASE_SHIFT)
|
||||
| ((mask & VAS_EBOOT_CS5536_IOD_ADDR_MASK)
|
||||
<< VAS_EBOOT_CS5536_IOD_MASK_SHIFT));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_p2d (VasEBoot_pci_device_t dev, int num, int dest, VasEBoot_uint32_t start)
|
||||
{
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_GL_P2D_START + num,
|
||||
(((VasEBoot_uint64_t) dest) << VAS_EBOOT_CS5536_P2D_DEST_SHIFT)
|
||||
| ((VasEBoot_uint64_t) (start >> VAS_EBOOT_CS5536_P2D_LOG_ALIGN)
|
||||
<< VAS_EBOOT_CS5536_P2D_BASE_SHIFT)
|
||||
| (((1 << (32 - VAS_EBOOT_CS5536_P2D_LOG_ALIGN)) - 1)
|
||||
<< VAS_EBOOT_CS5536_P2D_MASK_SHIFT));
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_cs5536_init_geode (VasEBoot_pci_device_t dev)
|
||||
{
|
||||
/* Enable more BARs. */
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_IRQ_MAP_BAR,
|
||||
VAS_EBOOT_CS5536_LBAR_TURN_ON | VAS_EBOOT_CS5536_LBAR_IRQ_MAP);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_MFGPT_BAR,
|
||||
VAS_EBOOT_CS5536_LBAR_TURN_ON | VAS_EBOOT_CS5536_LBAR_MFGPT);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_ACPI_BAR,
|
||||
VAS_EBOOT_CS5536_LBAR_TURN_ON | VAS_EBOOT_CS5536_LBAR_ACPI);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_PM_BAR,
|
||||
VAS_EBOOT_CS5536_LBAR_TURN_ON | VAS_EBOOT_CS5536_LBAR_PM);
|
||||
|
||||
/* Setup DIVIL. */
|
||||
#ifdef VAS_EBOOT_MACHINE_MIPS_LOONGSON
|
||||
switch (VasEBoot_arch_machine)
|
||||
{
|
||||
case VAS_EBOOT_ARCH_MACHINE_YEELOONG:
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO,
|
||||
VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_MODE_X86
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_F_REMAP
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1);
|
||||
break;
|
||||
case VAS_EBOOT_ARCH_MACHINE_FULOONG2F:
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO,
|
||||
VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_UART2_COM3
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_UART1_COM1
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_MODE_X86
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_F_REMAP
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0
|
||||
| VAS_EBOOT_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK,
|
||||
(~VAS_EBOOT_CS5536_DIVIL_LPC_INTERRUPTS) & 0xffff);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK,
|
||||
VAS_EBOOT_CS5536_DIVIL_LPC_INTERRUPTS);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL,
|
||||
VAS_EBOOT_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE);
|
||||
|
||||
/* Initialise USB controller. */
|
||||
/* FIXME: assign adresses dynamically. */
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_USB_OHCI_BASE,
|
||||
VAS_EBOOT_CS5536_MSR_USB_BASE_BUS_MASTER
|
||||
| VAS_EBOOT_CS5536_MSR_USB_BASE_MEMORY_ENABLE
|
||||
| 0x05024000);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_USB_EHCI_BASE,
|
||||
VAS_EBOOT_CS5536_MSR_USB_BASE_BUS_MASTER
|
||||
| VAS_EBOOT_CS5536_MSR_USB_BASE_MEMORY_ENABLE
|
||||
| (0x20ULL << VAS_EBOOT_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT)
|
||||
| 0x05023000);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_USB_CONTROLLER_BASE,
|
||||
VAS_EBOOT_CS5536_MSR_USB_BASE_BUS_MASTER
|
||||
| VAS_EBOOT_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05020000);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_USB_OPTION_CONTROLLER_BASE,
|
||||
VAS_EBOOT_CS5536_MSR_USB_BASE_MEMORY_ENABLE | 0x05022000);
|
||||
set_p2d (dev, 0, VAS_EBOOT_CS5536_DESTINATION_USB, 0x05020000);
|
||||
set_p2d (dev, 1, VAS_EBOOT_CS5536_DESTINATION_USB, 0x05022000);
|
||||
set_p2d (dev, 5, VAS_EBOOT_CS5536_DESTINATION_USB, 0x05024000);
|
||||
set_p2d (dev, 6, VAS_EBOOT_CS5536_DESTINATION_USB, 0x05023000);
|
||||
|
||||
{
|
||||
volatile VasEBoot_uint32_t *oc;
|
||||
|
||||
oc = VasEBoot_absolute_pointer (VasEBoot_pci_device_map_range (dev, 0x05022000,
|
||||
VAS_EBOOT_CS5536_USB_OPTION_REGS_SIZE));
|
||||
|
||||
oc[VAS_EBOOT_CS5536_USB_OPTION_REG_UOCMUX] =
|
||||
(oc[VAS_EBOOT_CS5536_USB_OPTION_REG_UOCMUX]
|
||||
& ~VAS_EBOOT_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK)
|
||||
| VAS_EBOOT_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC;
|
||||
VasEBoot_pci_device_unmap_range (dev, oc, VAS_EBOOT_CS5536_USB_OPTION_REGS_SIZE);
|
||||
}
|
||||
|
||||
/* Setup IDE controller. */
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_IDE_IO_BAR,
|
||||
VAS_EBOOT_CS5536_LBAR_IDE
|
||||
| VAS_EBOOT_CS5536_MSR_IDE_IO_BAR_UNITS);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_IDE_CFG,
|
||||
VAS_EBOOT_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE);
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_IDE_TIMING,
|
||||
(VAS_EBOOT_CS5536_MSR_IDE_TIMING_PIO0
|
||||
<< VAS_EBOOT_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT)
|
||||
| (VAS_EBOOT_CS5536_MSR_IDE_TIMING_PIO0
|
||||
<< VAS_EBOOT_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT));
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_IDE_CAS_TIMING,
|
||||
(VAS_EBOOT_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0
|
||||
<< VAS_EBOOT_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT)
|
||||
| (VAS_EBOOT_CS5536_MSR_IDE_CAS_TIMING_PIO0
|
||||
<< VAS_EBOOT_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT)
|
||||
| (VAS_EBOOT_CS5536_MSR_IDE_CAS_TIMING_PIO0
|
||||
<< VAS_EBOOT_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT));
|
||||
|
||||
/* Setup Geodelink PCI. */
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_GL_PCI_CTRL,
|
||||
(4ULL << VAS_EBOOT_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT)
|
||||
| (4ULL << VAS_EBOOT_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT)
|
||||
| (8ULL << VAS_EBOOT_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT)
|
||||
| VAS_EBOOT_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE
|
||||
| VAS_EBOOT_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE);
|
||||
|
||||
/* Setup windows. */
|
||||
set_io_space (dev, 0, VAS_EBOOT_CS5536_LBAR_SMBUS, VAS_EBOOT_CS5536_SMBUS_REGS_SIZE);
|
||||
set_io_space (dev, 1, VAS_EBOOT_CS5536_LBAR_GPIO, VAS_EBOOT_CS5536_GPIO_REGS_SIZE);
|
||||
set_io_space (dev, 2, VAS_EBOOT_CS5536_LBAR_MFGPT, VAS_EBOOT_CS5536_MFGPT_REGS_SIZE);
|
||||
set_io_space (dev, 3, VAS_EBOOT_CS5536_LBAR_IRQ_MAP, VAS_EBOOT_CS5536_IRQ_MAP_REGS_SIZE);
|
||||
set_io_space (dev, 4, VAS_EBOOT_CS5536_LBAR_PM, VAS_EBOOT_CS5536_PM_REGS_SIZE);
|
||||
set_io_space (dev, 5, VAS_EBOOT_CS5536_LBAR_ACPI, VAS_EBOOT_CS5536_ACPI_REGS_SIZE);
|
||||
set_iod (dev, 0, VAS_EBOOT_CS5536_DESTINATION_IDE, VAS_EBOOT_ATA_CH0_PORT1, 0xffff8);
|
||||
set_iod (dev, 1, VAS_EBOOT_CS5536_DESTINATION_ACC, VAS_EBOOT_CS5536_LBAR_ACC, 0xfff80);
|
||||
set_iod (dev, 2, VAS_EBOOT_CS5536_DESTINATION_IDE, VAS_EBOOT_CS5536_LBAR_IDE, 0xffff0);
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/* pci.c - Generic PCI interfaces. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/emu/misc.h>
|
||||
#include <VasEBoot/util/misc.h>
|
||||
|
||||
VasEBoot_pci_address_t
|
||||
VasEBoot_pci_make_address (VasEBoot_pci_device_t dev, int reg)
|
||||
{
|
||||
VasEBoot_pci_address_t ret;
|
||||
ret.dev = dev;
|
||||
ret.pos = reg;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_pci_iterate (VasEBoot_pci_iteratefunc_t hook, void *hook_data)
|
||||
{
|
||||
struct pci_device_iterator *iter;
|
||||
struct pci_slot_match slot;
|
||||
struct pci_device *dev;
|
||||
slot.domain = PCI_MATCH_ANY;
|
||||
slot.bus = PCI_MATCH_ANY;
|
||||
slot.dev = PCI_MATCH_ANY;
|
||||
slot.func = PCI_MATCH_ANY;
|
||||
iter = pci_slot_match_iterator_create (&slot);
|
||||
while ((dev = pci_device_next (iter)))
|
||||
hook (dev, dev->vendor_id | (dev->device_id << 16), hook_data);
|
||||
pci_iterator_destroy (iter);
|
||||
}
|
||||
|
||||
void *
|
||||
VasEBoot_pci_device_map_range (VasEBoot_pci_device_t dev, VasEBoot_addr_t base,
|
||||
VasEBoot_size_t size)
|
||||
{
|
||||
void *addr;
|
||||
int err;
|
||||
err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr);
|
||||
if (err)
|
||||
VasEBoot_util_error ("mapping 0x%llx failed (error %d)",
|
||||
(unsigned long long) base, err);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_pci_device_unmap_range (VasEBoot_pci_device_t dev, void *mem,
|
||||
VasEBoot_size_t size)
|
||||
{
|
||||
pci_device_unmap_range (dev, mem, size);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_INIT (emupci)
|
||||
{
|
||||
pci_system_init ();
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI (emupci)
|
||||
{
|
||||
pci_system_cleanup ();
|
||||
}
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/fdtbus.h>
|
||||
#include <VasEBoot/fdt.h>
|
||||
#include <VasEBoot/term.h>
|
||||
|
||||
static const void *dtb;
|
||||
static VasEBoot_size_t root_address_cells, root_size_cells;
|
||||
/* Pointer to this symbol signals invalid mapping. */
|
||||
char VasEBoot_fdtbus_invalid_mapping[1];
|
||||
|
||||
struct VasEBoot_fdtbus_dev *devs;
|
||||
struct VasEBoot_fdtbus_driver *drivers;
|
||||
|
||||
int
|
||||
VasEBoot_fdtbus_is_compatible (const char *compat_string,
|
||||
const struct VasEBoot_fdtbus_dev *dev)
|
||||
{
|
||||
VasEBoot_size_t compatible_size;
|
||||
const char *compatible = VasEBoot_fdt_get_prop (dtb, dev->node, "compatible",
|
||||
&compatible_size);
|
||||
if (!compatible)
|
||||
return 0;
|
||||
const char *compatible_end = compatible + compatible_size;
|
||||
while (compatible < compatible_end)
|
||||
{
|
||||
if (VasEBoot_strcmp (compat_string, compatible) == 0)
|
||||
return 1;
|
||||
compatible += VasEBoot_strlen (compatible) + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
fdtbus_scan (struct VasEBoot_fdtbus_dev *parent)
|
||||
{
|
||||
int node;
|
||||
for (node = VasEBoot_fdt_first_node (dtb, parent ? parent->node : 0); node >= 0;
|
||||
node = VasEBoot_fdt_next_node (dtb, node))
|
||||
{
|
||||
struct VasEBoot_fdtbus_dev *dev;
|
||||
struct VasEBoot_fdtbus_driver *driver;
|
||||
dev = VasEBoot_zalloc (sizeof (*dev));
|
||||
if (!dev)
|
||||
{
|
||||
VasEBoot_print_error ();
|
||||
return;
|
||||
}
|
||||
dev->node = node;
|
||||
dev->next = devs;
|
||||
dev->parent = parent;
|
||||
devs = dev;
|
||||
FOR_LIST_ELEMENTS(driver, drivers)
|
||||
if (!dev->driver && VasEBoot_fdtbus_is_compatible (driver->compatible, dev))
|
||||
{
|
||||
VasEBoot_dprintf ("fdtbus", "Attaching %s\n", driver->compatible);
|
||||
if (driver->attach (dev) == VAS_EBOOT_ERR_NONE)
|
||||
{
|
||||
VasEBoot_dprintf ("fdtbus", "Attached %s\n", driver->compatible);
|
||||
dev->driver = driver;
|
||||
break;
|
||||
}
|
||||
VasEBoot_print_error ();
|
||||
}
|
||||
fdtbus_scan (dev);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_fdtbus_register (struct VasEBoot_fdtbus_driver *driver)
|
||||
{
|
||||
struct VasEBoot_fdtbus_dev *dev;
|
||||
VasEBoot_dprintf ("fdtbus", "Registering %s\n", driver->compatible);
|
||||
VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&drivers),
|
||||
VAS_EBOOT_AS_LIST (driver));
|
||||
for (dev = devs; dev; dev = dev->next)
|
||||
if (!dev->driver && VasEBoot_fdtbus_is_compatible (driver->compatible, dev))
|
||||
{
|
||||
VasEBoot_dprintf ("fdtbus", "Attaching %s (%p)\n", driver->compatible, dev);
|
||||
if (driver->attach (dev) == VAS_EBOOT_ERR_NONE)
|
||||
{
|
||||
VasEBoot_dprintf ("fdtbus", "Attached %s\n", driver->compatible);
|
||||
dev->driver = driver;
|
||||
}
|
||||
VasEBoot_print_error ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_fdtbus_unregister (struct VasEBoot_fdtbus_driver *driver)
|
||||
{
|
||||
VasEBoot_list_remove (VAS_EBOOT_AS_LIST (driver));
|
||||
struct VasEBoot_fdtbus_dev *dev;
|
||||
for (dev = devs; dev; dev = dev->next)
|
||||
if (dev->driver == driver)
|
||||
{
|
||||
if (driver->detach)
|
||||
driver->detach(dev);
|
||||
dev->driver = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_fdtbus_init (const void *dtb_in, VasEBoot_size_t size)
|
||||
{
|
||||
if (!dtb_in || VasEBoot_fdt_check_header (dtb_in, size) < 0)
|
||||
VasEBoot_fatal ("invalid FDT");
|
||||
dtb = dtb_in;
|
||||
const VasEBoot_uint32_t *prop = VasEBoot_fdt_get_prop (dtb, 0, "#address-cells", 0);
|
||||
if (prop)
|
||||
root_address_cells = VasEBoot_be_to_cpu32 (*prop);
|
||||
else
|
||||
root_address_cells = 1;
|
||||
|
||||
prop = VasEBoot_fdt_get_prop (dtb, 0, "#size-cells", 0);
|
||||
if (prop)
|
||||
root_size_cells = VasEBoot_be_to_cpu32 (*prop);
|
||||
else
|
||||
root_size_cells = 1;
|
||||
|
||||
fdtbus_scan (0);
|
||||
}
|
||||
|
||||
static int
|
||||
get_address_cells (const struct VasEBoot_fdtbus_dev *dev)
|
||||
{
|
||||
const VasEBoot_uint32_t *prop;
|
||||
if (!dev)
|
||||
return root_address_cells;
|
||||
prop = VasEBoot_fdt_get_prop (dtb, dev->node, "#address-cells", 0);
|
||||
if (prop)
|
||||
return VasEBoot_be_to_cpu32 (*prop);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
get_size_cells (const struct VasEBoot_fdtbus_dev *dev)
|
||||
{
|
||||
const VasEBoot_uint32_t *prop;
|
||||
if (!dev)
|
||||
return root_size_cells;
|
||||
prop = VasEBoot_fdt_get_prop (dtb, dev->node, "#size-cells", 0);
|
||||
if (prop)
|
||||
return VasEBoot_be_to_cpu32 (*prop);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static VasEBoot_uint64_t
|
||||
get64 (const VasEBoot_uint32_t *reg, VasEBoot_size_t cells)
|
||||
{
|
||||
VasEBoot_uint64_t val = 0;
|
||||
if (cells >= 1)
|
||||
val = VasEBoot_be_to_cpu32 (reg[cells - 1]);
|
||||
if (cells >= 2)
|
||||
val |= ((VasEBoot_uint64_t) VasEBoot_be_to_cpu32 (reg[cells - 2])) << 32;
|
||||
return val;
|
||||
}
|
||||
|
||||
static volatile void *
|
||||
translate (const struct VasEBoot_fdtbus_dev *dev, const VasEBoot_uint32_t *reg)
|
||||
{
|
||||
volatile void *ret;
|
||||
const VasEBoot_uint32_t *ranges;
|
||||
VasEBoot_size_t ranges_size, cells_per_mapping;
|
||||
VasEBoot_size_t parent_address_cells, child_address_cells, child_size_cells;
|
||||
VasEBoot_size_t nmappings, i;
|
||||
if (dev == 0)
|
||||
{
|
||||
VasEBoot_uint64_t val;
|
||||
val = get64 (reg, root_address_cells);
|
||||
if (sizeof (void *) == 4 && (val >> 32))
|
||||
return VasEBoot_fdtbus_invalid_mapping;
|
||||
return (void *) (VasEBoot_addr_t) val;
|
||||
}
|
||||
ranges = VasEBoot_fdt_get_prop (dtb, dev->node, "ranges", &ranges_size);
|
||||
if (!ranges)
|
||||
return VasEBoot_fdtbus_invalid_mapping;
|
||||
if (ranges_size == 0)
|
||||
return translate (dev->parent, reg);
|
||||
parent_address_cells = get_address_cells (dev->parent);
|
||||
child_address_cells = get_address_cells (dev);
|
||||
child_size_cells = get_size_cells (dev);
|
||||
cells_per_mapping = parent_address_cells + child_address_cells + child_size_cells;
|
||||
nmappings = ranges_size / 4 / cells_per_mapping;
|
||||
for (i = 0; i < nmappings; i++)
|
||||
{
|
||||
const VasEBoot_uint32_t *child_addr = &ranges[i * cells_per_mapping];
|
||||
const VasEBoot_uint32_t *parent_addr = child_addr + child_address_cells;
|
||||
VasEBoot_uint64_t child_size = get64 (parent_addr + parent_address_cells, child_size_cells);
|
||||
|
||||
if (child_address_cells > 2 && VasEBoot_memcmp (reg, child_addr, (child_address_cells - 2) * 4) != 0)
|
||||
continue;
|
||||
if (get64 (reg, child_address_cells) < get64 (child_addr, child_address_cells))
|
||||
continue;
|
||||
|
||||
VasEBoot_uint64_t offset = get64 (reg, child_address_cells) - get64 (child_addr, child_address_cells);
|
||||
if (offset >= child_size)
|
||||
continue;
|
||||
|
||||
ret = translate (dev->parent, parent_addr);
|
||||
if (VasEBoot_fdtbus_is_mapping_valid (ret))
|
||||
ret = (volatile char *) ret + offset;
|
||||
return ret;
|
||||
}
|
||||
return VasEBoot_fdtbus_invalid_mapping;
|
||||
}
|
||||
|
||||
volatile void *
|
||||
VasEBoot_fdtbus_map_reg (const struct VasEBoot_fdtbus_dev *dev, int regno, VasEBoot_size_t *size)
|
||||
{
|
||||
VasEBoot_size_t address_cells, size_cells;
|
||||
address_cells = get_address_cells (dev->parent);
|
||||
size_cells = get_size_cells (dev->parent);
|
||||
const VasEBoot_uint32_t *reg = VasEBoot_fdt_get_prop (dtb, dev->node, "reg", 0);
|
||||
if (size && size_cells)
|
||||
*size = reg[(address_cells + size_cells) * regno + address_cells];
|
||||
if (size && !size_cells)
|
||||
*size = 0;
|
||||
return translate (dev->parent, reg + (address_cells + size_cells) * regno);
|
||||
}
|
||||
|
||||
const char *
|
||||
VasEBoot_fdtbus_get_name (const struct VasEBoot_fdtbus_dev *dev)
|
||||
{
|
||||
return VasEBoot_fdt_get_nodename (dtb, dev->node);
|
||||
}
|
||||
|
||||
const void *
|
||||
VasEBoot_fdtbus_get_prop (const struct VasEBoot_fdtbus_dev *dev,
|
||||
const char *name,
|
||||
VasEBoot_uint32_t *len)
|
||||
{
|
||||
return VasEBoot_fdt_get_prop (dtb, dev->node, name, len);
|
||||
}
|
||||
|
||||
const void *
|
||||
VasEBoot_fdtbus_get_fdt (void)
|
||||
{
|
||||
return dtb;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/ieee1275/ieee1275.h>
|
||||
|
||||
volatile void *
|
||||
VasEBoot_pci_device_map_range (VasEBoot_pci_device_t dev __attribute__ ((unused)),
|
||||
VasEBoot_addr_t base,
|
||||
VasEBoot_size_t size)
|
||||
{
|
||||
if (VasEBoot_ieee1275_test_flag (VAS_EBOOT_IEEE1275_FLAG_REAL_MODE))
|
||||
return (volatile void *) base;
|
||||
if (VasEBoot_ieee1275_map (base, base, size, 7))
|
||||
VasEBoot_fatal ("couldn't map 0x%lx", base);
|
||||
return (volatile void *) base;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_pci_device_unmap_range (VasEBoot_pci_device_t dev __attribute__ ((unused)),
|
||||
volatile void *mem __attribute__ ((unused)),
|
||||
VasEBoot_size_t size __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/* pci.c - Generic PCI interfaces. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2007,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm_private.h>
|
||||
#include <VasEBoot/cache.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* FIXME: correctly support 64-bit architectures. */
|
||||
/* #if VAS_EBOOT_TARGET_SIZEOF_VOID_P == 4 */
|
||||
struct VasEBoot_pci_dma_chunk *
|
||||
VasEBoot_memalign_dma32 (VasEBoot_size_t align, VasEBoot_size_t size)
|
||||
{
|
||||
void *ret;
|
||||
if (align < 64)
|
||||
align = 64;
|
||||
size = ALIGN_UP (size, align);
|
||||
ret = VasEBoot_memalign (align, size);
|
||||
#if VAS_EBOOT_CPU_SIZEOF_VOID_P == 8
|
||||
if ((VasEBoot_addr_t) ret >> 32)
|
||||
{
|
||||
/* Shouldn't happend since the only platform in this case is
|
||||
x86_64-efi and it skips any regions > 4GiB because
|
||||
of EFI bugs anyway. */
|
||||
VasEBoot_error (VAS_EBOOT_ERR_BUG, "allocation outside 32-bit range");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (!ret)
|
||||
return 0;
|
||||
VasEBoot_arch_sync_dma_caches (ret, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* FIXME: evil. */
|
||||
void
|
||||
VasEBoot_dma_free (struct VasEBoot_pci_dma_chunk *ch)
|
||||
{
|
||||
VasEBoot_size_t size = (((struct VasEBoot_mm_header *) ch) - 1)->size * VAS_EBOOT_MM_ALIGN;
|
||||
VasEBoot_arch_sync_dma_caches (ch, size);
|
||||
VasEBoot_free (ch);
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
#ifdef VAS_EBOOT_MACHINE_MIPS_LOONGSON
|
||||
volatile void *
|
||||
VasEBoot_dma_get_virt (struct VasEBoot_pci_dma_chunk *ch)
|
||||
{
|
||||
return (void *) ((((VasEBoot_uint32_t) ch) & 0x1fffffff) | 0xa0000000);
|
||||
}
|
||||
|
||||
VasEBoot_uint32_t
|
||||
VasEBoot_dma_get_phys (struct VasEBoot_pci_dma_chunk *ch)
|
||||
{
|
||||
return (((VasEBoot_uint32_t) ch) & 0x1fffffff) | 0x80000000;
|
||||
}
|
||||
#else
|
||||
|
||||
volatile void *
|
||||
VasEBoot_dma_get_virt (struct VasEBoot_pci_dma_chunk *ch)
|
||||
{
|
||||
return (void *) ch;
|
||||
}
|
||||
|
||||
VasEBoot_uint32_t
|
||||
VasEBoot_dma_get_phys (struct VasEBoot_pci_dma_chunk *ch)
|
||||
{
|
||||
return (VasEBoot_uint32_t) (VasEBoot_addr_t) ch;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
VasEBoot_pci_address_t
|
||||
VasEBoot_pci_make_address (VasEBoot_pci_device_t dev, int reg)
|
||||
{
|
||||
return (1 << 31) | (dev.bus << 16) | (dev.device << 11)
|
||||
| (dev.function << 8) | reg;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_pci_iterate (VasEBoot_pci_iteratefunc_t hook, void *hook_data)
|
||||
{
|
||||
VasEBoot_pci_device_t dev;
|
||||
VasEBoot_pci_address_t addr;
|
||||
VasEBoot_pci_id_t id;
|
||||
VasEBoot_uint32_t hdr;
|
||||
|
||||
for (dev.bus = 0; dev.bus < VAS_EBOOT_PCI_NUM_BUS; dev.bus++)
|
||||
{
|
||||
for (dev.device = 0; dev.device < VAS_EBOOT_PCI_NUM_DEVICES; dev.device++)
|
||||
{
|
||||
for (dev.function = 0; dev.function < 8; dev.function++)
|
||||
{
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_PCI_ID);
|
||||
id = VasEBoot_pci_read (addr);
|
||||
|
||||
/* Check if there is a device present. */
|
||||
if (id >> 16 == 0xFFFF)
|
||||
{
|
||||
if (dev.function == 0)
|
||||
/* Devices are required to implement function 0, so if
|
||||
it's missing then there is no device here. */
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hook (dev, id, hook_data))
|
||||
return;
|
||||
|
||||
/* Probe only func = 0 if the device if not multifunction */
|
||||
if (dev.function == 0)
|
||||
{
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_CACHELINE);
|
||||
hdr = VasEBoot_pci_read (addr);
|
||||
if (!(hdr & 0x800000))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VasEBoot_uint8_t
|
||||
VasEBoot_pci_find_capability (VasEBoot_pci_device_t dev, VasEBoot_uint8_t cap)
|
||||
{
|
||||
VasEBoot_uint8_t pos = 0x34;
|
||||
int ttl = 48;
|
||||
|
||||
while (ttl--)
|
||||
{
|
||||
VasEBoot_uint8_t id;
|
||||
VasEBoot_pci_address_t addr;
|
||||
|
||||
addr = VasEBoot_pci_make_address (dev, pos);
|
||||
pos = VasEBoot_pci_read_byte (addr);
|
||||
if (pos < 0x40)
|
||||
break;
|
||||
|
||||
pos &= ~3;
|
||||
|
||||
addr = VasEBoot_pci_make_address (dev, pos);
|
||||
id = VasEBoot_pci_read_byte (addr);
|
||||
|
||||
if (id == 0xff)
|
||||
break;
|
||||
|
||||
if (id == cap)
|
||||
return pos;
|
||||
pos++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
*
|
||||
* Copyright (C) 2012 Google Inc.
|
||||
* Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
*
|
||||
* This is based on depthcharge code.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/time.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/fdtbus.h>
|
||||
#include <VasEBoot/machine/kernel.h>
|
||||
|
||||
static VasEBoot_err_t
|
||||
spi_send (const struct VasEBoot_fdtbus_dev *dev, const void *data, VasEBoot_size_t sz)
|
||||
{
|
||||
const VasEBoot_uint8_t *ptr = data, *end = ptr + sz;
|
||||
volatile VasEBoot_uint32_t *spi = VasEBoot_fdtbus_map_reg (dev, 0, 0);
|
||||
spi[2] = 0;
|
||||
spi[1] = sz - 1;
|
||||
spi[0] = ((1 << 18) | spi[0]) & ~(1 << 19);
|
||||
spi[2] = 1;
|
||||
while (ptr < end)
|
||||
{
|
||||
while (spi[9] & 2);
|
||||
spi[256] = *ptr++;
|
||||
}
|
||||
while (spi[9] & 1);
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
spi_receive (const struct VasEBoot_fdtbus_dev *dev, void *data, VasEBoot_size_t sz)
|
||||
{
|
||||
VasEBoot_uint8_t *ptr = data, *end = ptr + sz;
|
||||
volatile VasEBoot_uint32_t *spi = VasEBoot_fdtbus_map_reg (dev, 0, 0);
|
||||
spi[2] = 0;
|
||||
spi[1] = sz - 1;
|
||||
spi[0] = ((1 << 19) | spi[0]) & ~(1 << 18);
|
||||
spi[2] = 1;
|
||||
while (ptr < end)
|
||||
{
|
||||
while (spi[9] & 8);
|
||||
*ptr++ = spi[512];
|
||||
}
|
||||
while (spi[9] & 1);
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
spi_start (const struct VasEBoot_fdtbus_dev *dev)
|
||||
{
|
||||
volatile VasEBoot_uint32_t *spi = VasEBoot_fdtbus_map_reg (dev, 0, 0);
|
||||
spi[3] = 1;
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
spi_stop (const struct VasEBoot_fdtbus_dev *dev)
|
||||
{
|
||||
volatile VasEBoot_uint32_t *spi = VasEBoot_fdtbus_map_reg (dev, 0, 0);
|
||||
spi[3] = 0;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
spi_attach(const struct VasEBoot_fdtbus_dev *dev)
|
||||
{
|
||||
if (!VasEBoot_fdtbus_is_mapping_valid (VasEBoot_fdtbus_map_reg (dev, 0, 0)))
|
||||
return VAS_EBOOT_ERR_IO;
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static struct VasEBoot_fdtbus_driver spi =
|
||||
{
|
||||
.compatible = "rockchip,rk3288-spi",
|
||||
.attach = spi_attach,
|
||||
.send = spi_send,
|
||||
.receive = spi_receive,
|
||||
.start = spi_start,
|
||||
.stop = spi_stop,
|
||||
};
|
||||
|
||||
void
|
||||
VasEBoot_rk3288_spi_init (void)
|
||||
{
|
||||
VasEBoot_fdtbus_register (&spi);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/* ehci.c - EHCI Support. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/time.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
#include <VasEBoot/fdtbus.h>
|
||||
|
||||
static VasEBoot_err_t
|
||||
ehci_attach(const struct VasEBoot_fdtbus_dev *dev)
|
||||
{
|
||||
VasEBoot_dprintf ("ehci", "Found generic-ehci\n");
|
||||
|
||||
VasEBoot_ehci_init_device (VasEBoot_fdtbus_map_reg (dev, 0, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct VasEBoot_fdtbus_driver ehci =
|
||||
{
|
||||
.compatible = "generic-ehci",
|
||||
.attach = ehci_attach
|
||||
};
|
||||
|
||||
void
|
||||
VasEBoot_ehci_pci_scan (void)
|
||||
{
|
||||
VasEBoot_fdtbus_register (&ehci);
|
||||
}
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
/* ehci.c - EHCI Support. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/cpu/pci.h>
|
||||
#include <VasEBoot/cs5536.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/time.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
|
||||
#define VAS_EBOOT_EHCI_PCI_SBRN_REG 0x60
|
||||
#define VAS_EBOOT_EHCI_ADDR_MEM_MASK (~0xff)
|
||||
|
||||
/* USBLEGSUP bits and related OS OWNED byte offset */
|
||||
enum
|
||||
{
|
||||
VAS_EBOOT_EHCI_BIOS_OWNED = (1 << 16),
|
||||
VAS_EBOOT_EHCI_OS_OWNED = (1 << 24)
|
||||
};
|
||||
|
||||
/* PCI iteration function... */
|
||||
static int
|
||||
VasEBoot_ehci_pci_iter (VasEBoot_pci_device_t dev, VasEBoot_pci_id_t pciid,
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
volatile VasEBoot_uint32_t *regs;
|
||||
VasEBoot_uint32_t base, base_h;
|
||||
VasEBoot_uint32_t eecp_offset;
|
||||
VasEBoot_uint32_t usblegsup = 0;
|
||||
VasEBoot_uint64_t maxtime;
|
||||
VasEBoot_uint32_t interf;
|
||||
VasEBoot_uint32_t subclass;
|
||||
VasEBoot_uint32_t class;
|
||||
VasEBoot_uint8_t release;
|
||||
VasEBoot_uint32_t class_code;
|
||||
|
||||
VasEBoot_dprintf ("ehci", "EHCI VasEBoot_ehci_pci_iter: begin\n");
|
||||
|
||||
if (pciid == VAS_EBOOT_CS5536_PCIID)
|
||||
{
|
||||
VasEBoot_uint64_t basereg;
|
||||
|
||||
basereg = VasEBoot_cs5536_read_msr (dev, VAS_EBOOT_CS5536_MSR_USB_EHCI_BASE);
|
||||
if (!(basereg & VAS_EBOOT_CS5536_MSR_USB_BASE_MEMORY_ENABLE))
|
||||
{
|
||||
/* Shouldn't happen. */
|
||||
VasEBoot_dprintf ("ehci", "No EHCI address is assigned\n");
|
||||
return 0;
|
||||
}
|
||||
base = (basereg & VAS_EBOOT_CS5536_MSR_USB_BASE_ADDR_MASK);
|
||||
basereg |= VAS_EBOOT_CS5536_MSR_USB_BASE_BUS_MASTER;
|
||||
basereg &= ~VAS_EBOOT_CS5536_MSR_USB_BASE_PME_ENABLED;
|
||||
basereg &= ~VAS_EBOOT_CS5536_MSR_USB_BASE_PME_STATUS;
|
||||
basereg &= ~VAS_EBOOT_CS5536_MSR_USB_BASE_SMI_ENABLE;
|
||||
VasEBoot_cs5536_write_msr (dev, VAS_EBOOT_CS5536_MSR_USB_EHCI_BASE, basereg);
|
||||
}
|
||||
else
|
||||
{
|
||||
VasEBoot_pci_address_t addr;
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_CLASS);
|
||||
class_code = VasEBoot_pci_read (addr) >> 8;
|
||||
interf = class_code & 0xFF;
|
||||
subclass = (class_code >> 8) & 0xFF;
|
||||
class = class_code >> 16;
|
||||
|
||||
/* If this is not an EHCI controller, just return. */
|
||||
if (class != 0x0c || subclass != 0x03 || interf != 0x20)
|
||||
return 0;
|
||||
|
||||
VasEBoot_dprintf ("ehci", "EHCI VasEBoot_ehci_pci_iter: class OK\n");
|
||||
|
||||
/* Check Serial Bus Release Number */
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_EHCI_PCI_SBRN_REG);
|
||||
release = VasEBoot_pci_read_byte (addr);
|
||||
if (release != 0x20)
|
||||
{
|
||||
VasEBoot_dprintf ("ehci", "EHCI VasEBoot_ehci_pci_iter: Wrong SBRN: %0x\n",
|
||||
release);
|
||||
return 0;
|
||||
}
|
||||
VasEBoot_dprintf ("ehci", "EHCI VasEBoot_ehci_pci_iter: bus rev. num. OK\n");
|
||||
|
||||
/* Determine EHCI EHCC registers base address. */
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_ADDRESS_REG0);
|
||||
base = VasEBoot_pci_read (addr);
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_ADDRESS_REG1);
|
||||
base_h = VasEBoot_pci_read (addr);
|
||||
/* Stop if registers are mapped above 4G - VAS_EBOOT does not currently
|
||||
* work with registers mapped above 4G */
|
||||
if (((base & VAS_EBOOT_PCI_ADDR_MEM_TYPE_MASK) != VAS_EBOOT_PCI_ADDR_MEM_TYPE_32)
|
||||
&& (base_h != 0))
|
||||
{
|
||||
VasEBoot_dprintf ("ehci",
|
||||
"EHCI VasEBoot_ehci_pci_iter: registers above 4G are not supported\n");
|
||||
return 0;
|
||||
}
|
||||
base &= VAS_EBOOT_PCI_ADDR_MEM_MASK;
|
||||
if (!base)
|
||||
{
|
||||
VasEBoot_dprintf ("ehci",
|
||||
"EHCI: EHCI is not mapped\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_COMMAND);
|
||||
VasEBoot_pci_write_word(addr,
|
||||
VAS_EBOOT_PCI_COMMAND_MEM_ENABLED
|
||||
| VAS_EBOOT_PCI_COMMAND_BUS_MASTER
|
||||
| VasEBoot_pci_read_word(addr));
|
||||
|
||||
VasEBoot_dprintf ("ehci", "EHCI VasEBoot_ehci_pci_iter: 32-bit EHCI OK\n");
|
||||
}
|
||||
|
||||
VasEBoot_dprintf ("ehci", "EHCI VasEBoot_ehci_pci_iter: iobase of EHCC: %08x\n",
|
||||
(base & VAS_EBOOT_EHCI_ADDR_MEM_MASK));
|
||||
|
||||
regs = VasEBoot_pci_device_map_range (dev,
|
||||
(base & VAS_EBOOT_EHCI_ADDR_MEM_MASK),
|
||||
0x100);
|
||||
|
||||
/* Is there EECP ? */
|
||||
eecp_offset = (VasEBoot_le_to_cpu32 (regs[2]) >> 8) & 0xff;
|
||||
|
||||
/* Determine and change ownership. */
|
||||
/* EECP offset valid in HCCPARAMS */
|
||||
/* Ownership can be changed via EECP only */
|
||||
if (pciid != VAS_EBOOT_CS5536_PCIID && eecp_offset >= 0x40)
|
||||
{
|
||||
VasEBoot_pci_address_t pciaddr_eecp;
|
||||
pciaddr_eecp = VasEBoot_pci_make_address (dev, eecp_offset);
|
||||
|
||||
usblegsup = VasEBoot_pci_read (pciaddr_eecp);
|
||||
if (usblegsup & VAS_EBOOT_EHCI_BIOS_OWNED)
|
||||
{
|
||||
VasEBoot_boot_time ("Taking ownership of EHCI controller");
|
||||
VasEBoot_dprintf ("ehci",
|
||||
"EHCI VasEBoot_ehci_pci_iter: EHCI owned by: BIOS\n");
|
||||
/* Ownership change - set OS_OWNED bit */
|
||||
VasEBoot_pci_write (pciaddr_eecp, usblegsup | VAS_EBOOT_EHCI_OS_OWNED);
|
||||
/* Ensure PCI register is written */
|
||||
VasEBoot_pci_read (pciaddr_eecp);
|
||||
|
||||
/* Wait for finish of ownership change, EHCI specification
|
||||
* doesn't say how long it can take... */
|
||||
maxtime = VasEBoot_get_time_ms () + 1000;
|
||||
while ((VasEBoot_pci_read (pciaddr_eecp) & VAS_EBOOT_EHCI_BIOS_OWNED)
|
||||
&& (VasEBoot_get_time_ms () < maxtime));
|
||||
if (VasEBoot_pci_read (pciaddr_eecp) & VAS_EBOOT_EHCI_BIOS_OWNED)
|
||||
{
|
||||
VasEBoot_dprintf ("ehci",
|
||||
"EHCI VasEBoot_ehci_pci_iter: EHCI change ownership timeout");
|
||||
/* Change ownership in "hard way" - reset BIOS ownership */
|
||||
VasEBoot_pci_write (pciaddr_eecp, VAS_EBOOT_EHCI_OS_OWNED);
|
||||
/* Ensure PCI register is written */
|
||||
VasEBoot_pci_read (pciaddr_eecp);
|
||||
}
|
||||
}
|
||||
else if (usblegsup & VAS_EBOOT_EHCI_OS_OWNED)
|
||||
/* XXX: What to do in this case - nothing ? Can it happen ? */
|
||||
VasEBoot_dprintf ("ehci", "EHCI VasEBoot_ehci_pci_iter: EHCI owned by: OS\n");
|
||||
else
|
||||
{
|
||||
VasEBoot_dprintf ("ehci",
|
||||
"EHCI VasEBoot_ehci_pci_iter: EHCI owned by: NONE\n");
|
||||
/* XXX: What to do in this case ? Can it happen ?
|
||||
* Is code below correct ? */
|
||||
/* Ownership change - set OS_OWNED bit */
|
||||
VasEBoot_pci_write (pciaddr_eecp, VAS_EBOOT_EHCI_OS_OWNED);
|
||||
/* Ensure PCI register is written */
|
||||
VasEBoot_pci_read (pciaddr_eecp);
|
||||
}
|
||||
|
||||
/* Disable SMI, just to be sure. */
|
||||
pciaddr_eecp = VasEBoot_pci_make_address (dev, eecp_offset + 4);
|
||||
VasEBoot_pci_write (pciaddr_eecp, 0);
|
||||
/* Ensure PCI register is written */
|
||||
VasEBoot_pci_read (pciaddr_eecp);
|
||||
}
|
||||
|
||||
VasEBoot_dprintf ("ehci", "inithw: EHCI VasEBoot_ehci_pci_iter: ownership OK\n");
|
||||
|
||||
VasEBoot_ehci_init_device (regs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_ehci_pci_scan (void)
|
||||
{
|
||||
VasEBoot_pci_iterate (VasEBoot_ehci_pci_iter, NULL);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/serial.h>
|
||||
#include <VasEBoot/usbserial.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
void
|
||||
VasEBoot_usbserial_fini (struct VasEBoot_serial_port *port)
|
||||
{
|
||||
port->usbdev->config[port->configno].interf[port->interfno].detach_hook = 0;
|
||||
port->usbdev->config[port->configno].interf[port->interfno].attached = 0;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_usbserial_detach (VasEBoot_usb_device_t usbdev, int configno, int interfno)
|
||||
{
|
||||
static struct VasEBoot_serial_port *port;
|
||||
port = usbdev->config[configno].interf[interfno].detach_data;
|
||||
|
||||
VasEBoot_serial_unregister (port);
|
||||
}
|
||||
|
||||
static int usbnum = 0;
|
||||
|
||||
int
|
||||
VasEBoot_usbserial_attach (VasEBoot_usb_device_t usbdev, int configno, int interfno,
|
||||
struct VasEBoot_serial_driver *driver, int in_endp,
|
||||
int out_endp)
|
||||
{
|
||||
struct VasEBoot_serial_port *port;
|
||||
int j;
|
||||
struct VasEBoot_usb_desc_if *interf;
|
||||
VasEBoot_usb_err_t err = VAS_EBOOT_USB_ERR_NONE;
|
||||
|
||||
interf = usbdev->config[configno].interf[interfno].descif;
|
||||
|
||||
port = VasEBoot_zalloc (sizeof (*port));
|
||||
if (!port)
|
||||
{
|
||||
VasEBoot_print_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
port->name = VasEBoot_xasprintf ("usb%d", usbnum++);
|
||||
if (!port->name)
|
||||
{
|
||||
VasEBoot_free (port);
|
||||
VasEBoot_print_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
port->usbdev = usbdev;
|
||||
port->driver = driver;
|
||||
for (j = 0; j < interf->endpointcnt; j++)
|
||||
{
|
||||
struct VasEBoot_usb_desc_endp *endp;
|
||||
endp = &usbdev->config[0].interf[interfno].descendp[j];
|
||||
|
||||
if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2
|
||||
&& (in_endp == VAS_EBOOT_USB_SERIAL_ENDPOINT_LAST_MATCHING
|
||||
|| in_endp == endp->endp_addr))
|
||||
{
|
||||
/* Bulk IN endpoint. */
|
||||
port->in_endp = endp;
|
||||
}
|
||||
else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2
|
||||
&& (out_endp == VAS_EBOOT_USB_SERIAL_ENDPOINT_LAST_MATCHING
|
||||
|| out_endp == endp->endp_addr))
|
||||
{
|
||||
/* Bulk OUT endpoint. */
|
||||
port->out_endp = endp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure device */
|
||||
if (port->out_endp && port->in_endp)
|
||||
err = VasEBoot_usb_set_configuration (usbdev, configno + 1);
|
||||
|
||||
if (!port->out_endp || !port->in_endp || err)
|
||||
{
|
||||
VasEBoot_free (port->name);
|
||||
VasEBoot_free (port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
port->configno = configno;
|
||||
port->interfno = interfno;
|
||||
|
||||
VasEBoot_serial_config_defaults (port);
|
||||
VasEBoot_serial_register (port);
|
||||
|
||||
port->usbdev->config[port->configno].interf[port->interfno].detach_hook
|
||||
= VasEBoot_usbserial_detach;
|
||||
port->usbdev->config[port->configno].interf[port->interfno].detach_data
|
||||
= port;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
VasEBoot_usbserial_fetch (struct VasEBoot_serial_port *port, VasEBoot_size_t header_size)
|
||||
{
|
||||
VasEBoot_usb_err_t err;
|
||||
VasEBoot_size_t actual;
|
||||
|
||||
if (port->bufstart < port->bufend)
|
||||
return port->buf[port->bufstart++];
|
||||
|
||||
err = VasEBoot_usb_bulk_read_extended (port->usbdev, port->in_endp,
|
||||
sizeof (port->buf), port->buf, 10,
|
||||
&actual);
|
||||
if (err != VAS_EBOOT_USB_ERR_NONE)
|
||||
return -1;
|
||||
|
||||
port->bufstart = header_size;
|
||||
port->bufend = actual;
|
||||
if (port->bufstart >= port->bufend)
|
||||
return -1;
|
||||
|
||||
return port->buf[port->bufstart++];
|
||||
}
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/serial.h>
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
#include <VasEBoot/usbserial.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
enum
|
||||
{
|
||||
VAS_EBOOT_FTDI_MODEM_CTRL = 0x01,
|
||||
VAS_EBOOT_FTDI_FLOW_CTRL = 0x02,
|
||||
VAS_EBOOT_FTDI_SPEED_CTRL = 0x03,
|
||||
VAS_EBOOT_FTDI_DATA_CTRL = 0x04
|
||||
};
|
||||
|
||||
#define VAS_EBOOT_FTDI_MODEM_CTRL_DTRRTS 3
|
||||
#define VAS_EBOOT_FTDI_FLOW_CTRL_DTRRTS 3
|
||||
|
||||
/* Convert speed to divisor. */
|
||||
static VasEBoot_uint32_t
|
||||
get_divisor (unsigned int speed)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* The structure for speed vs. divisor. */
|
||||
struct divisor
|
||||
{
|
||||
unsigned int speed;
|
||||
VasEBoot_uint32_t div;
|
||||
};
|
||||
|
||||
/* The table which lists common configurations. */
|
||||
/* Computed with a division formula with 3MHz as base frequency. */
|
||||
static struct divisor divisor_tab[] =
|
||||
{
|
||||
{ 2400, 0x04e2 },
|
||||
{ 4800, 0x0271 },
|
||||
{ 9600, 0x4138 },
|
||||
{ 19200, 0x809c },
|
||||
{ 38400, 0xc04e },
|
||||
{ 57600, 0xc034 },
|
||||
{ 115200, 0x001a }
|
||||
};
|
||||
|
||||
/* Set the baud rate. */
|
||||
for (i = 0; i < ARRAY_SIZE (divisor_tab); i++)
|
||||
if (divisor_tab[i].speed == speed)
|
||||
return divisor_tab[i].div;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
real_config (struct VasEBoot_serial_port *port)
|
||||
{
|
||||
VasEBoot_uint32_t divisor;
|
||||
const VasEBoot_uint16_t parities[] = {
|
||||
[VAS_EBOOT_SERIAL_PARITY_NONE] = 0x0000,
|
||||
[VAS_EBOOT_SERIAL_PARITY_ODD] = 0x0100,
|
||||
[VAS_EBOOT_SERIAL_PARITY_EVEN] = 0x0200
|
||||
};
|
||||
const VasEBoot_uint16_t stop_bits[] = {
|
||||
[VAS_EBOOT_SERIAL_STOP_BITS_1] = 0x0000,
|
||||
[VAS_EBOOT_SERIAL_STOP_BITS_1_5] = 0x0800,
|
||||
[VAS_EBOOT_SERIAL_STOP_BITS_2] = 0x1000,
|
||||
};
|
||||
|
||||
if (port->configured)
|
||||
return;
|
||||
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
VAS_EBOOT_FTDI_MODEM_CTRL,
|
||||
port->config.rtscts ? VAS_EBOOT_FTDI_MODEM_CTRL_DTRRTS : 0,
|
||||
0, 0, 0);
|
||||
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
VAS_EBOOT_FTDI_FLOW_CTRL,
|
||||
port->config.rtscts ? VAS_EBOOT_FTDI_FLOW_CTRL_DTRRTS : 0,
|
||||
0, 0, 0);
|
||||
|
||||
divisor = get_divisor (port->config.speed);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
VAS_EBOOT_FTDI_SPEED_CTRL,
|
||||
divisor & 0xffff, divisor >> 16, 0, 0);
|
||||
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
VAS_EBOOT_FTDI_DATA_CTRL,
|
||||
parities[port->config.parity]
|
||||
| stop_bits[port->config.stop_bits]
|
||||
| port->config.word_len, 0, 0, 0);
|
||||
|
||||
port->configured = 1;
|
||||
}
|
||||
|
||||
/* Fetch a key. */
|
||||
static int
|
||||
ftdi_hw_fetch (struct VasEBoot_serial_port *port)
|
||||
{
|
||||
real_config (port);
|
||||
|
||||
return VasEBoot_usbserial_fetch (port, 2);
|
||||
}
|
||||
|
||||
/* Put a character. */
|
||||
static void
|
||||
ftdi_hw_put (struct VasEBoot_serial_port *port, const int c)
|
||||
{
|
||||
char cc = c;
|
||||
|
||||
real_config (port);
|
||||
|
||||
VasEBoot_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc);
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
ftdi_hw_configure (struct VasEBoot_serial_port *port,
|
||||
struct VasEBoot_serial_config *config)
|
||||
{
|
||||
VasEBoot_uint16_t divisor;
|
||||
|
||||
divisor = get_divisor (config->speed);
|
||||
if (divisor == 0)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("unsupported serial port speed"));
|
||||
|
||||
if (config->parity != VAS_EBOOT_SERIAL_PARITY_NONE
|
||||
&& config->parity != VAS_EBOOT_SERIAL_PARITY_ODD
|
||||
&& config->parity != VAS_EBOOT_SERIAL_PARITY_EVEN)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("unsupported serial port parity"));
|
||||
|
||||
if (config->stop_bits != VAS_EBOOT_SERIAL_STOP_BITS_1
|
||||
&& config->stop_bits != VAS_EBOOT_SERIAL_STOP_BITS_1_5
|
||||
&& config->stop_bits != VAS_EBOOT_SERIAL_STOP_BITS_2)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("unsupported serial port stop bits number"));
|
||||
|
||||
if (config->word_len < 5 || config->word_len > 8)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("unsupported serial port word length"));
|
||||
|
||||
port->config = *config;
|
||||
port->configured = 0;
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static struct VasEBoot_serial_driver VasEBoot_ftdi_driver =
|
||||
{
|
||||
.configure = ftdi_hw_configure,
|
||||
.fetch = ftdi_hw_fetch,
|
||||
.put = ftdi_hw_put,
|
||||
.fini = VasEBoot_usbserial_fini
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
VasEBoot_uint16_t vendor, product;
|
||||
} products[] =
|
||||
{
|
||||
{0x0403, 0x6001} /* QEMU virtual USBserial. */
|
||||
};
|
||||
|
||||
static int
|
||||
VasEBoot_ftdi_attach (VasEBoot_usb_device_t usbdev, int configno, int interfno)
|
||||
{
|
||||
unsigned j;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE (products); j++)
|
||||
if (usbdev->descdev.vendorid == products[j].vendor
|
||||
&& usbdev->descdev.prodid == products[j].product)
|
||||
break;
|
||||
if (j == ARRAY_SIZE (products))
|
||||
return 0;
|
||||
|
||||
return VasEBoot_usbserial_attach (usbdev, configno, interfno,
|
||||
&VasEBoot_ftdi_driver,
|
||||
VAS_EBOOT_USB_SERIAL_ENDPOINT_LAST_MATCHING,
|
||||
VAS_EBOOT_USB_SERIAL_ENDPOINT_LAST_MATCHING);
|
||||
}
|
||||
|
||||
static struct VasEBoot_usb_attach_desc attach_hook =
|
||||
{
|
||||
.class = 0xff,
|
||||
.hook = VasEBoot_ftdi_attach
|
||||
};
|
||||
|
||||
VAS_EBOOT_MOD_INIT(usbserial_ftdi)
|
||||
{
|
||||
VasEBoot_usb_register_attach_hook_class (&attach_hook);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(usbserial_ftdi)
|
||||
{
|
||||
VasEBoot_serial_unregister_driver (&VasEBoot_ftdi_driver);
|
||||
VasEBoot_usb_unregister_attach_hook_class (&attach_hook);
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/serial.h>
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
#include <VasEBoot/usbserial.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Convert speed to divisor. */
|
||||
static VasEBoot_uint32_t
|
||||
is_speed_supported (unsigned int speed)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int supported[] = { 2400, 4800, 9600, 19200, 38400, 57600, 115200};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (supported); i++)
|
||||
if (supported[i] == speed)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define VAS_EBOOT_PL2303_REQUEST_SET_CONFIG 0x20
|
||||
#define VAS_EBOOT_PL2303_STOP_BITS_1 0x0
|
||||
#define VAS_EBOOT_PL2303_STOP_BITS_1_5 0x1
|
||||
#define VAS_EBOOT_PL2303_STOP_BITS_2 0x2
|
||||
|
||||
#define VAS_EBOOT_PL2303_PARITY_NONE 0
|
||||
#define VAS_EBOOT_PL2303_PARITY_ODD 1
|
||||
#define VAS_EBOOT_PL2303_PARITY_EVEN 2
|
||||
|
||||
struct VasEBoot_pl2303_config
|
||||
{
|
||||
VasEBoot_uint32_t speed;
|
||||
VasEBoot_uint8_t stop_bits;
|
||||
VasEBoot_uint8_t parity;
|
||||
VasEBoot_uint8_t word_len;
|
||||
} VAS_EBOOT_PACKED;
|
||||
|
||||
static void
|
||||
real_config (struct VasEBoot_serial_port *port)
|
||||
{
|
||||
struct VasEBoot_pl2303_config config_pl2303;
|
||||
char xx;
|
||||
|
||||
if (port->configured)
|
||||
return;
|
||||
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_IN,
|
||||
1, 0x8484, 0, 1, &xx);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
1, 0x0404, 0, 0, 0);
|
||||
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_IN,
|
||||
1, 0x8484, 0, 1, &xx);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_IN,
|
||||
1, 0x8383, 0, 1, &xx);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_IN,
|
||||
1, 0x8484, 0, 1, &xx);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
1, 0x0404, 1, 0, 0);
|
||||
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_IN,
|
||||
1, 0x8484, 0, 1, &xx);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_IN,
|
||||
1, 0x8383, 0, 1, &xx);
|
||||
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
1, 0, 1, 0, 0);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
1, 1, 0, 0, 0);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
1, 2, 0x44, 0, 0);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
1, 8, 0, 0, 0);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
1, 9, 0, 0, 0);
|
||||
|
||||
if (port->config.stop_bits == VAS_EBOOT_SERIAL_STOP_BITS_2)
|
||||
config_pl2303.stop_bits = VAS_EBOOT_PL2303_STOP_BITS_2;
|
||||
else if (port->config.stop_bits == VAS_EBOOT_SERIAL_STOP_BITS_1_5)
|
||||
config_pl2303.stop_bits = VAS_EBOOT_PL2303_STOP_BITS_1_5;
|
||||
else
|
||||
config_pl2303.stop_bits = VAS_EBOOT_PL2303_STOP_BITS_1;
|
||||
|
||||
switch (port->config.parity)
|
||||
{
|
||||
case VAS_EBOOT_SERIAL_PARITY_NONE:
|
||||
config_pl2303.parity = VAS_EBOOT_PL2303_PARITY_NONE;
|
||||
break;
|
||||
case VAS_EBOOT_SERIAL_PARITY_ODD:
|
||||
config_pl2303.parity = VAS_EBOOT_PL2303_PARITY_ODD;
|
||||
break;
|
||||
case VAS_EBOOT_SERIAL_PARITY_EVEN:
|
||||
config_pl2303.parity = VAS_EBOOT_PL2303_PARITY_EVEN;
|
||||
break;
|
||||
}
|
||||
|
||||
config_pl2303.word_len = port->config.word_len;
|
||||
config_pl2303.speed = port->config.speed;
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_CLASS_INTERFACE_OUT,
|
||||
VAS_EBOOT_PL2303_REQUEST_SET_CONFIG, 0, 0,
|
||||
sizeof (config_pl2303), (char *) &config_pl2303);
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_CLASS_INTERFACE_OUT,
|
||||
0x22, 3, 0, 0, 0);
|
||||
|
||||
VasEBoot_usb_control_msg (port->usbdev, VAS_EBOOT_USB_REQTYPE_VENDOR_OUT,
|
||||
1, 0, port->config.rtscts ? 0x61 : 0, 0, 0);
|
||||
port->configured = 1;
|
||||
}
|
||||
|
||||
/* Fetch a key. */
|
||||
static int
|
||||
pl2303_hw_fetch (struct VasEBoot_serial_port *port)
|
||||
{
|
||||
real_config (port);
|
||||
|
||||
return VasEBoot_usbserial_fetch (port, 0);
|
||||
}
|
||||
|
||||
/* Put a character. */
|
||||
static void
|
||||
pl2303_hw_put (struct VasEBoot_serial_port *port, const int c)
|
||||
{
|
||||
char cc = c;
|
||||
|
||||
real_config (port);
|
||||
|
||||
VasEBoot_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc);
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
pl2303_hw_configure (struct VasEBoot_serial_port *port,
|
||||
struct VasEBoot_serial_config *config)
|
||||
{
|
||||
if (!is_speed_supported (config->speed))
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("unsupported serial port speed"));
|
||||
|
||||
if (config->parity != VAS_EBOOT_SERIAL_PARITY_NONE
|
||||
&& config->parity != VAS_EBOOT_SERIAL_PARITY_ODD
|
||||
&& config->parity != VAS_EBOOT_SERIAL_PARITY_EVEN)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("unsupported serial port parity"));
|
||||
|
||||
if (config->stop_bits != VAS_EBOOT_SERIAL_STOP_BITS_1
|
||||
&& config->stop_bits != VAS_EBOOT_SERIAL_STOP_BITS_1_5
|
||||
&& config->stop_bits != VAS_EBOOT_SERIAL_STOP_BITS_2)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("unsupported serial port stop bits number"));
|
||||
|
||||
if (config->word_len < 5 || config->word_len > 8)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("unsupported serial port word length"));
|
||||
|
||||
port->config = *config;
|
||||
port->configured = 0;
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static struct VasEBoot_serial_driver VasEBoot_pl2303_driver =
|
||||
{
|
||||
.configure = pl2303_hw_configure,
|
||||
.fetch = pl2303_hw_fetch,
|
||||
.put = pl2303_hw_put,
|
||||
.fini = VasEBoot_usbserial_fini
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
VasEBoot_uint16_t vendor, product;
|
||||
} products[] =
|
||||
{
|
||||
{0x067b, 0x2303}
|
||||
};
|
||||
|
||||
static int
|
||||
VasEBoot_pl2303_attach (VasEBoot_usb_device_t usbdev, int configno, int interfno)
|
||||
{
|
||||
unsigned j;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE (products); j++)
|
||||
if (usbdev->descdev.vendorid == products[j].vendor
|
||||
&& usbdev->descdev.prodid == products[j].product)
|
||||
break;
|
||||
if (j == ARRAY_SIZE (products))
|
||||
return 0;
|
||||
|
||||
return VasEBoot_usbserial_attach (usbdev, configno, interfno,
|
||||
&VasEBoot_pl2303_driver,
|
||||
VAS_EBOOT_USB_SERIAL_ENDPOINT_LAST_MATCHING,
|
||||
VAS_EBOOT_USB_SERIAL_ENDPOINT_LAST_MATCHING);
|
||||
}
|
||||
|
||||
static struct VasEBoot_usb_attach_desc attach_hook =
|
||||
{
|
||||
.class = 0xff,
|
||||
.hook = VasEBoot_pl2303_attach
|
||||
};
|
||||
|
||||
VAS_EBOOT_MOD_INIT(usbserial_pl2303)
|
||||
{
|
||||
VasEBoot_usb_register_attach_hook_class (&attach_hook);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(usbserial_pl2303)
|
||||
{
|
||||
VasEBoot_serial_unregister_driver (&VasEBoot_pl2303_driver);
|
||||
VasEBoot_usb_unregister_attach_hook_class (&attach_hook);
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/serial.h>
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
#include <VasEBoot/usbserial.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
||||
/* Fetch a key. */
|
||||
static int
|
||||
usbdebug_late_hw_fetch (struct VasEBoot_serial_port *port)
|
||||
{
|
||||
return VasEBoot_usbserial_fetch (port, 0);
|
||||
}
|
||||
|
||||
/* Put a character. */
|
||||
static void
|
||||
usbdebug_late_hw_put (struct VasEBoot_serial_port *port, const int c)
|
||||
{
|
||||
char cc = c;
|
||||
|
||||
VasEBoot_usb_bulk_write (port->usbdev, port->out_endp, 1, &cc);
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
usbdebug_late_hw_configure (struct VasEBoot_serial_port *port __attribute__ ((unused)),
|
||||
struct VasEBoot_serial_config *config __attribute__ ((unused)))
|
||||
{
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static struct VasEBoot_serial_driver VasEBoot_usbdebug_late_driver =
|
||||
{
|
||||
.configure = usbdebug_late_hw_configure,
|
||||
.fetch = usbdebug_late_hw_fetch,
|
||||
.put = usbdebug_late_hw_put,
|
||||
.fini = VasEBoot_usbserial_fini
|
||||
};
|
||||
|
||||
static int
|
||||
VasEBoot_usbdebug_late_attach (VasEBoot_usb_device_t usbdev, int configno, int interfno)
|
||||
{
|
||||
VasEBoot_usb_err_t err;
|
||||
struct VasEBoot_usb_desc_debug debugdesc;
|
||||
|
||||
err = VasEBoot_usb_get_descriptor (usbdev, VAS_EBOOT_USB_DESCRIPTOR_DEBUG, configno,
|
||||
sizeof (debugdesc), (char *) &debugdesc);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
return VasEBoot_usbserial_attach (usbdev, configno, interfno,
|
||||
&VasEBoot_usbdebug_late_driver,
|
||||
debugdesc.in_endp, debugdesc.out_endp);
|
||||
}
|
||||
|
||||
static struct VasEBoot_usb_attach_desc attach_hook =
|
||||
{
|
||||
.class = 0xff,
|
||||
.hook = VasEBoot_usbdebug_late_attach
|
||||
};
|
||||
|
||||
VAS_EBOOT_MOD_INIT(usbserial_usbdebug_late)
|
||||
{
|
||||
VasEBoot_usb_register_attach_hook_class (&attach_hook);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(usbserial_usbdebug_late)
|
||||
{
|
||||
VasEBoot_serial_unregister_driver (&VasEBoot_usbdebug_late_driver);
|
||||
VasEBoot_usb_unregister_attach_hook_class (&attach_hook);
|
||||
}
|
||||
|
|
@ -0,0 +1,871 @@
|
|||
/* uhci.c - UHCI Support. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
#include <VasEBoot/usbtrans.h>
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/cpu/io.h>
|
||||
#include <VasEBoot/time.h>
|
||||
#include <VasEBoot/cpu/pci.h>
|
||||
#include <VasEBoot/disk.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define VAS_EBOOT_UHCI_IOMASK (0x7FF << 5)
|
||||
|
||||
#define N_QH 256
|
||||
#define N_TD 640
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VAS_EBOOT_UHCI_REG_USBCMD = 0x00,
|
||||
VAS_EBOOT_UHCI_REG_USBINTR = 0x04,
|
||||
VAS_EBOOT_UHCI_REG_FLBASEADD = 0x08,
|
||||
VAS_EBOOT_UHCI_REG_PORTSC1 = 0x10,
|
||||
VAS_EBOOT_UHCI_REG_PORTSC2 = 0x12,
|
||||
VAS_EBOOT_UHCI_REG_USBLEGSUP = 0xc0
|
||||
} VasEBoot_uhci_reg_t;
|
||||
|
||||
enum
|
||||
{
|
||||
VAS_EBOOT_UHCI_DETECT_CHANGED = (1 << 1),
|
||||
VAS_EBOOT_UHCI_DETECT_HAVE_DEVICE = 1,
|
||||
VAS_EBOOT_UHCI_DETECT_LOW_SPEED = (1 << 8)
|
||||
};
|
||||
|
||||
/* R/WC legacy support bits */
|
||||
enum
|
||||
{
|
||||
VAS_EBOOT_UHCI_LEGSUP_END_A20GATE = (1 << 15),
|
||||
VAS_EBOOT_UHCI_TRAP_BY_64H_WSTAT = (1 << 11),
|
||||
VAS_EBOOT_UHCI_TRAP_BY_64H_RSTAT = (1 << 10),
|
||||
VAS_EBOOT_UHCI_TRAP_BY_60H_WSTAT = (1 << 9),
|
||||
VAS_EBOOT_UHCI_TRAP_BY_60H_RSTAT = (1 << 8)
|
||||
};
|
||||
|
||||
/* Reset all legacy support - clear all R/WC bits and all R/W bits */
|
||||
#define VAS_EBOOT_UHCI_RESET_LEGSUP_SMI ( VAS_EBOOT_UHCI_LEGSUP_END_A20GATE \
|
||||
| VAS_EBOOT_UHCI_TRAP_BY_64H_WSTAT \
|
||||
| VAS_EBOOT_UHCI_TRAP_BY_64H_RSTAT \
|
||||
| VAS_EBOOT_UHCI_TRAP_BY_60H_WSTAT \
|
||||
| VAS_EBOOT_UHCI_TRAP_BY_60H_RSTAT )
|
||||
|
||||
/* Some UHCI commands */
|
||||
#define VAS_EBOOT_UHCI_CMD_RUN_STOP (1 << 0)
|
||||
#define VAS_EBOOT_UHCI_CMD_HCRESET (1 << 1)
|
||||
#define VAS_EBOOT_UHCI_CMD_MAXP (1 << 7)
|
||||
|
||||
/* Important bits in structures */
|
||||
#define VAS_EBOOT_UHCI_LINK_TERMINATE 1
|
||||
#define VAS_EBOOT_UHCI_LINK_QUEUE_HEAD 2
|
||||
|
||||
enum
|
||||
{
|
||||
VAS_EBOOT_UHCI_REG_PORTSC_CONNECT_CHANGED = 0x0002,
|
||||
VAS_EBOOT_UHCI_REG_PORTSC_PORT_ENABLED = 0x0004,
|
||||
VAS_EBOOT_UHCI_REG_PORTSC_RESUME = 0x0040,
|
||||
VAS_EBOOT_UHCI_REG_PORTSC_RESET = 0x0200,
|
||||
VAS_EBOOT_UHCI_REG_PORTSC_SUSPEND = 0x1000,
|
||||
VAS_EBOOT_UHCI_REG_PORTSC_RW = VAS_EBOOT_UHCI_REG_PORTSC_PORT_ENABLED
|
||||
| VAS_EBOOT_UHCI_REG_PORTSC_RESUME | VAS_EBOOT_UHCI_REG_PORTSC_RESET
|
||||
| VAS_EBOOT_UHCI_REG_PORTSC_SUSPEND,
|
||||
/* These bits should not be written as 1 unless we really need it */
|
||||
VAS_EBOOT_UHCI_PORTSC_RWC = ((1 << 1) | (1 << 3) | (1 << 11) | (3 << 13))
|
||||
};
|
||||
|
||||
/* UHCI Queue Head. */
|
||||
struct VasEBoot_uhci_qh
|
||||
{
|
||||
/* Queue head link pointer which points to the next queue head. */
|
||||
VasEBoot_uint32_t linkptr;
|
||||
|
||||
/* Queue element link pointer which points to the first data object
|
||||
within the queue. */
|
||||
VasEBoot_uint32_t elinkptr;
|
||||
|
||||
/* Queue heads are aligned on 16 bytes, pad so a queue head is 16
|
||||
bytes so we can store many in a 4K page. */
|
||||
VasEBoot_uint8_t pad[8];
|
||||
} VAS_EBOOT_PACKED;
|
||||
|
||||
/* UHCI Transfer Descriptor. */
|
||||
struct VasEBoot_uhci_td
|
||||
{
|
||||
/* Pointer to the next TD in the list. */
|
||||
VasEBoot_uint32_t linkptr;
|
||||
|
||||
/* Control and status bits. */
|
||||
VasEBoot_uint32_t ctrl_status;
|
||||
|
||||
/* All information required to transfer the Token packet. */
|
||||
VasEBoot_uint32_t token;
|
||||
|
||||
/* A pointer to the data buffer, UHCI requires this pointer to be 32
|
||||
bits. */
|
||||
VasEBoot_uint32_t buffer;
|
||||
|
||||
/* Another linkptr that is not overwritten by the Host Controller.
|
||||
This is VAS_EBOOT specific. */
|
||||
VasEBoot_uint32_t linkptr2;
|
||||
|
||||
/* 3 additional 32 bits words reserved for the Host Controller Driver. */
|
||||
VasEBoot_uint32_t data[3];
|
||||
} VAS_EBOOT_PACKED;
|
||||
|
||||
typedef volatile struct VasEBoot_uhci_td *VasEBoot_uhci_td_t;
|
||||
typedef volatile struct VasEBoot_uhci_qh *VasEBoot_uhci_qh_t;
|
||||
|
||||
struct VasEBoot_uhci
|
||||
{
|
||||
VasEBoot_port_t iobase;
|
||||
volatile VasEBoot_uint32_t *framelist_virt;
|
||||
VasEBoot_uint32_t framelist_phys;
|
||||
struct VasEBoot_pci_dma_chunk *framelist_chunk;
|
||||
|
||||
/* N_QH Queue Heads. */
|
||||
struct VasEBoot_pci_dma_chunk *qh_chunk;
|
||||
volatile VasEBoot_uhci_qh_t qh_virt;
|
||||
VasEBoot_uint32_t qh_phys;
|
||||
|
||||
/* N_TD Transfer Descriptors. */
|
||||
struct VasEBoot_pci_dma_chunk *td_chunk;
|
||||
volatile VasEBoot_uhci_td_t td_virt;
|
||||
VasEBoot_uint32_t td_phys;
|
||||
|
||||
/* Free Transfer Descriptors. */
|
||||
VasEBoot_uhci_td_t tdfree;
|
||||
|
||||
int qh_busy[N_QH];
|
||||
|
||||
struct VasEBoot_uhci *next;
|
||||
};
|
||||
|
||||
static struct VasEBoot_uhci *uhci;
|
||||
|
||||
static VasEBoot_uint16_t
|
||||
VasEBoot_uhci_readreg16 (struct VasEBoot_uhci *u, VasEBoot_uhci_reg_t reg)
|
||||
{
|
||||
return VasEBoot_inw (u->iobase + reg);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static VasEBoot_uint32_t
|
||||
VasEBoot_uhci_readreg32 (struct VasEBoot_uhci *u, VasEBoot_uhci_reg_t reg)
|
||||
{
|
||||
return VasEBoot_inl (u->iobase + reg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
VasEBoot_uhci_writereg16 (struct VasEBoot_uhci *u,
|
||||
VasEBoot_uhci_reg_t reg, VasEBoot_uint16_t val)
|
||||
{
|
||||
VasEBoot_outw (val, u->iobase + reg);
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_uhci_writereg32 (struct VasEBoot_uhci *u,
|
||||
VasEBoot_uhci_reg_t reg, VasEBoot_uint32_t val)
|
||||
{
|
||||
VasEBoot_outl (val, u->iobase + reg);
|
||||
}
|
||||
|
||||
/* Iterate over all PCI devices. Determine if a device is an UHCI
|
||||
controller. If this is the case, initialize it. */
|
||||
static int
|
||||
VasEBoot_uhci_pci_iter (VasEBoot_pci_device_t dev,
|
||||
VasEBoot_pci_id_t pciid __attribute__((unused)),
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_uint32_t class_code;
|
||||
VasEBoot_uint32_t class;
|
||||
VasEBoot_uint32_t subclass;
|
||||
VasEBoot_uint32_t interf;
|
||||
VasEBoot_uint32_t base;
|
||||
VasEBoot_uint32_t fp;
|
||||
VasEBoot_pci_address_t addr;
|
||||
struct VasEBoot_uhci *u;
|
||||
int i;
|
||||
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_CLASS);
|
||||
class_code = VasEBoot_pci_read (addr) >> 8;
|
||||
|
||||
interf = class_code & 0xFF;
|
||||
subclass = (class_code >> 8) & 0xFF;
|
||||
class = class_code >> 16;
|
||||
|
||||
/* If this is not an UHCI controller, just return. */
|
||||
if (class != 0x0c || subclass != 0x03 || interf != 0x00)
|
||||
return 0;
|
||||
|
||||
/* Determine IO base address. */
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_ADDRESS_REG4);
|
||||
base = VasEBoot_pci_read (addr);
|
||||
/* Stop if there is no IO space base address defined. */
|
||||
if ((base & VAS_EBOOT_PCI_ADDR_SPACE_MASK) != VAS_EBOOT_PCI_ADDR_SPACE_IO)
|
||||
return 0;
|
||||
|
||||
if ((base & VAS_EBOOT_UHCI_IOMASK) == 0)
|
||||
return 0;
|
||||
|
||||
/* Set bus master - needed for coreboot or broken BIOSes */
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_COMMAND);
|
||||
VasEBoot_pci_write_word(addr, VAS_EBOOT_PCI_COMMAND_IO_ENABLED
|
||||
| VAS_EBOOT_PCI_COMMAND_BUS_MASTER
|
||||
| VAS_EBOOT_PCI_COMMAND_MEM_ENABLED
|
||||
| VasEBoot_pci_read_word (addr));
|
||||
|
||||
VasEBoot_dprintf ("uhci", "base = %x\n", base);
|
||||
|
||||
/* Allocate memory for the controller and register it. */
|
||||
u = VasEBoot_zalloc (sizeof (*u));
|
||||
if (! u)
|
||||
return 1;
|
||||
|
||||
u->iobase = (base & VAS_EBOOT_UHCI_IOMASK) + VAS_EBOOT_MACHINE_PCI_IO_BASE;
|
||||
|
||||
/* Reset PIRQ and SMI */
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_UHCI_REG_USBLEGSUP);
|
||||
VasEBoot_pci_write_word(addr, VAS_EBOOT_UHCI_RESET_LEGSUP_SMI);
|
||||
/* Reset the HC */
|
||||
VasEBoot_uhci_writereg16(u, VAS_EBOOT_UHCI_REG_USBCMD, VAS_EBOOT_UHCI_CMD_HCRESET);
|
||||
VasEBoot_millisleep(5);
|
||||
/* Disable interrupts and commands (just to be safe) */
|
||||
VasEBoot_uhci_writereg16(u, VAS_EBOOT_UHCI_REG_USBINTR, 0);
|
||||
/* Finish HC reset, HC remains disabled */
|
||||
VasEBoot_uhci_writereg16(u, VAS_EBOOT_UHCI_REG_USBCMD, 0);
|
||||
/* Read back to be sure PCI write is done */
|
||||
VasEBoot_uhci_readreg16(u, VAS_EBOOT_UHCI_REG_USBCMD);
|
||||
|
||||
/* Reserve a page for the frame list. */
|
||||
u->framelist_chunk = VasEBoot_memalign_dma32 (4096, 4096);
|
||||
if (! u->framelist_chunk)
|
||||
goto fail;
|
||||
u->framelist_virt = VasEBoot_dma_get_virt (u->framelist_chunk);
|
||||
u->framelist_phys = VasEBoot_dma_get_phys (u->framelist_chunk);
|
||||
|
||||
VasEBoot_dprintf ("uhci",
|
||||
"class=0x%02x 0x%02x interface 0x%02x base=0x%x framelist=%p\n",
|
||||
class, subclass, interf, u->iobase, u->framelist_virt);
|
||||
|
||||
/* The QH pointer of UHCI is only 32 bits, make sure this
|
||||
code works on on 64 bits architectures. */
|
||||
u->qh_chunk = VasEBoot_memalign_dma32 (4096, sizeof(struct VasEBoot_uhci_qh) * N_QH);
|
||||
if (! u->qh_chunk)
|
||||
goto fail;
|
||||
u->qh_virt = VasEBoot_dma_get_virt (u->qh_chunk);
|
||||
u->qh_phys = VasEBoot_dma_get_phys (u->qh_chunk);
|
||||
|
||||
/* The TD pointer of UHCI is only 32 bits, make sure this
|
||||
code works on on 64 bits architectures. */
|
||||
u->td_chunk = VasEBoot_memalign_dma32 (4096, sizeof(struct VasEBoot_uhci_td) * N_TD);
|
||||
if (! u->td_chunk)
|
||||
goto fail;
|
||||
u->td_virt = VasEBoot_dma_get_virt (u->td_chunk);
|
||||
u->td_phys = VasEBoot_dma_get_phys (u->td_chunk);
|
||||
|
||||
VasEBoot_dprintf ("uhci", "QH=%p, TD=%p\n",
|
||||
u->qh_virt, u->td_virt);
|
||||
|
||||
/* Link all Transfer Descriptors in a list of available Transfer
|
||||
Descriptors. */
|
||||
for (i = 0; i < N_TD; i++)
|
||||
u->td_virt[i].linkptr = u->td_phys + (i + 1) * sizeof(struct VasEBoot_uhci_td);
|
||||
u->td_virt[N_TD - 2].linkptr = 0;
|
||||
u->tdfree = u->td_virt;
|
||||
|
||||
/* Setup the frame list pointers. Since no isochronous transfers
|
||||
are and will be supported, they all point to the (same!) queue
|
||||
head. */
|
||||
fp = u->qh_phys & (~15);
|
||||
/* Mark this as a queue head. */
|
||||
fp |= 2;
|
||||
for (i = 0; i < 1024; i++)
|
||||
u->framelist_virt[i] = fp;
|
||||
/* Program the framelist address into the UHCI controller. */
|
||||
VasEBoot_uhci_writereg32 (u, VAS_EBOOT_UHCI_REG_FLBASEADD, u->framelist_phys);
|
||||
|
||||
/* Make the Queue Heads point to each other. */
|
||||
for (i = 0; i < N_QH; i++)
|
||||
{
|
||||
/* Point to the next QH. */
|
||||
u->qh_virt[i].linkptr = ((u->qh_phys
|
||||
+ (i + 1) * sizeof(struct VasEBoot_uhci_qh))
|
||||
& (~15));
|
||||
|
||||
/* This is a QH. */
|
||||
u->qh_virt[i].linkptr |= VAS_EBOOT_UHCI_LINK_QUEUE_HEAD;
|
||||
|
||||
/* For the moment, do not point to a Transfer Descriptor. These
|
||||
are set at transfer time, so just terminate it. */
|
||||
u->qh_virt[i].elinkptr = 1;
|
||||
}
|
||||
|
||||
/* The last Queue Head should terminate. */
|
||||
u->qh_virt[N_QH - 1].linkptr = 1;
|
||||
|
||||
/* Enable UHCI again. */
|
||||
VasEBoot_uhci_writereg16 (u, VAS_EBOOT_UHCI_REG_USBCMD,
|
||||
VAS_EBOOT_UHCI_CMD_RUN_STOP | VAS_EBOOT_UHCI_CMD_MAXP);
|
||||
|
||||
/* UHCI is initialized and ready for transfers. */
|
||||
VasEBoot_dprintf ("uhci", "UHCI initialized\n");
|
||||
|
||||
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
VasEBoot_uint16_t frnum;
|
||||
|
||||
frnum = VasEBoot_uhci_readreg16 (u, 6);
|
||||
VasEBoot_dprintf ("uhci", "Framenum=%d\n", frnum);
|
||||
VasEBoot_millisleep (100);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Link to uhci now that initialisation is successful. */
|
||||
u->next = uhci;
|
||||
uhci = u;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (u)
|
||||
{
|
||||
VasEBoot_dma_free (u->qh_chunk);
|
||||
VasEBoot_dma_free (u->framelist_chunk);
|
||||
}
|
||||
VasEBoot_free (u);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_uhci_inithw (void)
|
||||
{
|
||||
VasEBoot_pci_iterate (VasEBoot_uhci_pci_iter, NULL);
|
||||
}
|
||||
|
||||
static VasEBoot_uhci_td_t
|
||||
VasEBoot_alloc_td (struct VasEBoot_uhci *u)
|
||||
{
|
||||
VasEBoot_uhci_td_t ret;
|
||||
|
||||
/* Check if there is a Transfer Descriptor available. */
|
||||
if (! u->tdfree)
|
||||
return NULL;
|
||||
|
||||
ret = u->tdfree;
|
||||
u->tdfree = VasEBoot_dma_phys2virt (u->tdfree->linkptr, u->td_chunk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_free_td (struct VasEBoot_uhci *u, VasEBoot_uhci_td_t td)
|
||||
{
|
||||
td->linkptr = VasEBoot_dma_virt2phys (u->tdfree, u->td_chunk);
|
||||
u->tdfree = td;
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_free_queue (struct VasEBoot_uhci *u, VasEBoot_uhci_qh_t qh, VasEBoot_uhci_td_t td,
|
||||
VasEBoot_usb_transfer_t transfer, VasEBoot_size_t *actual)
|
||||
{
|
||||
int i; /* Index of TD in transfer */
|
||||
|
||||
u->qh_busy[qh - u->qh_virt] = 0;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
/* Free the TDs in this queue and set last_trans. */
|
||||
for (i=0; td; i++)
|
||||
{
|
||||
VasEBoot_uhci_td_t tdprev;
|
||||
|
||||
VasEBoot_dprintf ("uhci", "Freeing %p\n", td);
|
||||
/* Check state of TD and possibly set last_trans */
|
||||
if (transfer && (td->linkptr & 1))
|
||||
transfer->last_trans = i;
|
||||
|
||||
*actual += (td->ctrl_status + 1) & 0x7ff;
|
||||
|
||||
/* Unlink the queue. */
|
||||
tdprev = td;
|
||||
if (!td->linkptr2)
|
||||
td = 0;
|
||||
else
|
||||
td = VasEBoot_dma_phys2virt (td->linkptr2, u->td_chunk);
|
||||
|
||||
/* Free the TD. */
|
||||
VasEBoot_free_td (u, tdprev);
|
||||
}
|
||||
}
|
||||
|
||||
static VasEBoot_uhci_qh_t
|
||||
VasEBoot_alloc_qh (struct VasEBoot_uhci *u,
|
||||
VasEBoot_transaction_type_t tr __attribute__((unused)))
|
||||
{
|
||||
int i;
|
||||
VasEBoot_uhci_qh_t qh;
|
||||
|
||||
/* Look for a Queue Head for this transfer. Skip the first QH if
|
||||
this is a Interrupt Transfer. */
|
||||
#if 0
|
||||
if (tr == VAS_EBOOT_USB_TRANSACTION_TYPE_INTERRUPT)
|
||||
i = 0;
|
||||
else
|
||||
#endif
|
||||
i = 1;
|
||||
|
||||
for (; i < N_QH; i++)
|
||||
{
|
||||
if (!u->qh_busy[i])
|
||||
break;
|
||||
}
|
||||
qh = &u->qh_virt[i];
|
||||
if (i == N_QH)
|
||||
{
|
||||
VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"no free queue heads available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u->qh_busy[qh - u->qh_virt] = 1;
|
||||
|
||||
return qh;
|
||||
}
|
||||
|
||||
static VasEBoot_uhci_td_t
|
||||
VasEBoot_uhci_transaction (struct VasEBoot_uhci *u, unsigned int endp,
|
||||
VasEBoot_transfer_type_t type, unsigned int addr,
|
||||
unsigned int toggle, VasEBoot_size_t size,
|
||||
VasEBoot_uint32_t data, VasEBoot_usb_speed_t speed)
|
||||
{
|
||||
VasEBoot_uhci_td_t td;
|
||||
static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
|
||||
|
||||
/* XXX: Check if data is <4GB. If it isn't, just copy stuff around.
|
||||
This is only relevant for 64 bits architectures. */
|
||||
|
||||
/* Grab a free Transfer Descriptor and initialize it. */
|
||||
td = VasEBoot_alloc_td (u);
|
||||
if (! td)
|
||||
{
|
||||
VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"no transfer descriptors available for UHCI transfer");
|
||||
return 0;
|
||||
}
|
||||
|
||||
VasEBoot_dprintf ("uhci",
|
||||
"transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%lu data=0x%x td=%p\n",
|
||||
endp, type, addr, toggle, (unsigned long) size, data, td);
|
||||
|
||||
/* Don't point to any TD, just terminate. */
|
||||
td->linkptr = 1;
|
||||
|
||||
/* Active! Only retry a transfer 3 times. */
|
||||
td->ctrl_status = (1 << 23) | (3 << 27) |
|
||||
((speed == VAS_EBOOT_USB_SPEED_LOW) ? (1 << 26) : 0);
|
||||
|
||||
/* If zero bytes are transmitted, size is 0x7FF. Otherwise size is
|
||||
size-1. */
|
||||
if (size == 0)
|
||||
size = 0x7FF;
|
||||
else
|
||||
size = size - 1;
|
||||
|
||||
/* Setup whatever is required for the token packet. */
|
||||
td->token = ((size << 21) | (toggle << 19) | (endp << 15)
|
||||
| (addr << 8) | tf[type]);
|
||||
|
||||
td->buffer = data;
|
||||
|
||||
return td;
|
||||
}
|
||||
|
||||
struct VasEBoot_uhci_transfer_controller_data
|
||||
{
|
||||
VasEBoot_uhci_qh_t qh;
|
||||
VasEBoot_uhci_td_t td_first;
|
||||
};
|
||||
|
||||
static VasEBoot_usb_err_t
|
||||
VasEBoot_uhci_setup_transfer (VasEBoot_usb_controller_t dev,
|
||||
VasEBoot_usb_transfer_t transfer)
|
||||
{
|
||||
struct VasEBoot_uhci *u = (struct VasEBoot_uhci *) dev->data;
|
||||
VasEBoot_uhci_td_t td;
|
||||
VasEBoot_uhci_td_t td_prev = NULL;
|
||||
int i;
|
||||
struct VasEBoot_uhci_transfer_controller_data *cdata;
|
||||
|
||||
cdata = VasEBoot_malloc (sizeof (*cdata));
|
||||
if (!cdata)
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
|
||||
cdata->td_first = NULL;
|
||||
|
||||
/* Allocate a queue head for the transfer queue. */
|
||||
cdata->qh = VasEBoot_alloc_qh (u, VAS_EBOOT_USB_TRANSACTION_TYPE_CONTROL);
|
||||
if (! cdata->qh)
|
||||
{
|
||||
VasEBoot_free (cdata);
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
VasEBoot_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase);
|
||||
|
||||
for (i = 0; i < transfer->transcnt; i++)
|
||||
{
|
||||
VasEBoot_usb_transaction_t tr = &transfer->transactions[i];
|
||||
|
||||
td = VasEBoot_uhci_transaction (u, transfer->endpoint & 15, tr->pid,
|
||||
transfer->devaddr, tr->toggle,
|
||||
tr->size, tr->data,
|
||||
transfer->dev->speed);
|
||||
if (! td)
|
||||
{
|
||||
VasEBoot_size_t actual = 0;
|
||||
/* Terminate and free. */
|
||||
if (td_prev)
|
||||
{
|
||||
td_prev->linkptr2 = 0;
|
||||
td_prev->linkptr = 1;
|
||||
}
|
||||
|
||||
if (cdata->td_first)
|
||||
VasEBoot_free_queue (u, cdata->qh, cdata->td_first, NULL, &actual);
|
||||
|
||||
VasEBoot_free (cdata);
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
if (! cdata->td_first)
|
||||
cdata->td_first = td;
|
||||
else
|
||||
{
|
||||
td_prev->linkptr2 = VasEBoot_dma_virt2phys (td, u->td_chunk);
|
||||
td_prev->linkptr = VasEBoot_dma_virt2phys (td, u->td_chunk);
|
||||
td_prev->linkptr |= 4;
|
||||
}
|
||||
td_prev = td;
|
||||
}
|
||||
td_prev->linkptr2 = 0;
|
||||
td_prev->linkptr = 1;
|
||||
|
||||
VasEBoot_dprintf ("uhci", "setup transaction %d\n", transfer->type);
|
||||
|
||||
/* Link it into the queue and terminate. Now the transaction can
|
||||
take place. */
|
||||
cdata->qh->elinkptr = VasEBoot_dma_virt2phys (cdata->td_first, u->td_chunk);
|
||||
|
||||
VasEBoot_dprintf ("uhci", "initiate transaction\n");
|
||||
|
||||
transfer->controller_data = cdata;
|
||||
|
||||
return VAS_EBOOT_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_usb_err_t
|
||||
VasEBoot_uhci_check_transfer (VasEBoot_usb_controller_t dev,
|
||||
VasEBoot_usb_transfer_t transfer,
|
||||
VasEBoot_size_t *actual)
|
||||
{
|
||||
struct VasEBoot_uhci *u = (struct VasEBoot_uhci *) dev->data;
|
||||
VasEBoot_uhci_td_t errtd;
|
||||
struct VasEBoot_uhci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
if (cdata->qh->elinkptr & ~0x0f)
|
||||
errtd = VasEBoot_dma_phys2virt (cdata->qh->elinkptr & ~0x0f, u->qh_chunk);
|
||||
else
|
||||
errtd = 0;
|
||||
|
||||
if (errtd)
|
||||
{
|
||||
VasEBoot_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p, %x\n",
|
||||
errtd->ctrl_status, errtd->buffer & (~15), errtd,
|
||||
cdata->qh->elinkptr);
|
||||
}
|
||||
|
||||
/* Check if the transaction completed. */
|
||||
if (cdata->qh->elinkptr & 1)
|
||||
{
|
||||
VasEBoot_dprintf ("uhci", "transaction complete\n");
|
||||
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
cdata->qh->elinkptr = 1;
|
||||
VasEBoot_free_queue (u, cdata->qh, cdata->td_first, transfer, actual);
|
||||
VasEBoot_free (cdata);
|
||||
return VAS_EBOOT_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
if (errtd && !(errtd->ctrl_status & (1 << 23)))
|
||||
{
|
||||
VasEBoot_usb_err_t err = VAS_EBOOT_USB_ERR_NONE;
|
||||
|
||||
/* Check if the endpoint is stalled. */
|
||||
if (errtd->ctrl_status & (1 << 22))
|
||||
err = VAS_EBOOT_USB_ERR_STALL;
|
||||
|
||||
/* Check if an error related to the data buffer occurred. */
|
||||
else if (errtd->ctrl_status & (1 << 21))
|
||||
err = VAS_EBOOT_USB_ERR_DATA;
|
||||
|
||||
/* Check if a babble error occurred. */
|
||||
else if (errtd->ctrl_status & (1 << 20))
|
||||
err = VAS_EBOOT_USB_ERR_BABBLE;
|
||||
|
||||
/* Check if a NAK occurred. */
|
||||
else if (errtd->ctrl_status & (1 << 19))
|
||||
err = VAS_EBOOT_USB_ERR_NAK;
|
||||
|
||||
/* Check if a timeout occurred. */
|
||||
else if (errtd->ctrl_status & (1 << 18))
|
||||
err = VAS_EBOOT_USB_ERR_TIMEOUT;
|
||||
|
||||
/* Check if a bitstuff error occurred. */
|
||||
else if (errtd->ctrl_status & (1 << 17))
|
||||
err = VAS_EBOOT_USB_ERR_BITSTUFF;
|
||||
|
||||
if (err)
|
||||
{
|
||||
VasEBoot_dprintf ("uhci", "transaction failed\n");
|
||||
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
cdata->qh->elinkptr = 1;
|
||||
VasEBoot_free_queue (u, cdata->qh, cdata->td_first, transfer, actual);
|
||||
VasEBoot_free (cdata);
|
||||
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall through, no errors occurred, so the QH might be
|
||||
updated. */
|
||||
VasEBoot_dprintf ("uhci", "transaction fallthrough\n");
|
||||
|
||||
return VAS_EBOOT_USB_ERR_WAIT;
|
||||
}
|
||||
|
||||
static VasEBoot_usb_err_t
|
||||
VasEBoot_uhci_cancel_transfer (VasEBoot_usb_controller_t dev,
|
||||
VasEBoot_usb_transfer_t transfer)
|
||||
{
|
||||
struct VasEBoot_uhci *u = (struct VasEBoot_uhci *) dev->data;
|
||||
VasEBoot_size_t actual;
|
||||
struct VasEBoot_uhci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
|
||||
VasEBoot_dprintf ("uhci", "transaction cancel\n");
|
||||
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
cdata->qh->elinkptr = 1;
|
||||
VasEBoot_free_queue (u, cdata->qh, cdata->td_first, transfer, &actual);
|
||||
VasEBoot_free (cdata);
|
||||
|
||||
return VAS_EBOOT_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
VasEBoot_uhci_iterate (VasEBoot_usb_controller_iterate_hook_t hook, void *hook_data)
|
||||
{
|
||||
struct VasEBoot_uhci *u;
|
||||
struct VasEBoot_usb_controller dev;
|
||||
|
||||
for (u = uhci; u; u = u->next)
|
||||
{
|
||||
dev.data = u;
|
||||
if (hook (&dev, hook_data))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_usb_err_t
|
||||
VasEBoot_uhci_portstatus (VasEBoot_usb_controller_t dev,
|
||||
unsigned int port, unsigned int enable)
|
||||
{
|
||||
struct VasEBoot_uhci *u = (struct VasEBoot_uhci *) dev->data;
|
||||
int reg;
|
||||
unsigned int status;
|
||||
VasEBoot_uint64_t endtime;
|
||||
|
||||
VasEBoot_dprintf ("uhci", "portstatus, iobase:%08x\n", u->iobase);
|
||||
|
||||
VasEBoot_dprintf ("uhci", "enable=%d port=%d\n", enable, port);
|
||||
|
||||
if (port == 0)
|
||||
reg = VAS_EBOOT_UHCI_REG_PORTSC1;
|
||||
else if (port == 1)
|
||||
reg = VAS_EBOOT_UHCI_REG_PORTSC2;
|
||||
else
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
|
||||
status = VasEBoot_uhci_readreg16 (u, reg);
|
||||
VasEBoot_dprintf ("uhci", "detect=0x%02x\n", status);
|
||||
|
||||
if (!enable) /* We don't need reset port */
|
||||
{
|
||||
/* Disable the port. */
|
||||
VasEBoot_uhci_writereg16 (u, reg, 0 << 2);
|
||||
VasEBoot_dprintf ("uhci", "waiting for the port to be disabled\n");
|
||||
endtime = VasEBoot_get_time_ms () + 1000;
|
||||
while ((VasEBoot_uhci_readreg16 (u, reg) & (1 << 2)))
|
||||
if (VasEBoot_get_time_ms () > endtime)
|
||||
return VAS_EBOOT_USB_ERR_TIMEOUT;
|
||||
|
||||
status = VasEBoot_uhci_readreg16 (u, reg);
|
||||
VasEBoot_dprintf ("uhci", ">3detect=0x%02x\n", status);
|
||||
return VAS_EBOOT_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Reset the port. */
|
||||
status = VasEBoot_uhci_readreg16 (u, reg) & ~VAS_EBOOT_UHCI_PORTSC_RWC;
|
||||
VasEBoot_uhci_writereg16 (u, reg, status | (1 << 9));
|
||||
VasEBoot_uhci_readreg16 (u, reg); /* Ensure it is writen... */
|
||||
|
||||
/* Wait for the reset to complete. XXX: How long exactly? */
|
||||
VasEBoot_millisleep (50); /* For root hub should be nominaly 50ms */
|
||||
status = VasEBoot_uhci_readreg16 (u, reg) & ~VAS_EBOOT_UHCI_PORTSC_RWC;
|
||||
VasEBoot_uhci_writereg16 (u, reg, status & ~(1 << 9));
|
||||
VasEBoot_uhci_readreg16 (u, reg); /* Ensure it is writen... */
|
||||
|
||||
/* Note: some debug prints were removed because they affected reset/enable timing. */
|
||||
|
||||
VasEBoot_millisleep (1); /* Probably not needed at all or only few microsecs. */
|
||||
|
||||
/* Reset bits Connect & Enable Status Change */
|
||||
status = VasEBoot_uhci_readreg16 (u, reg) & ~VAS_EBOOT_UHCI_PORTSC_RWC;
|
||||
VasEBoot_uhci_writereg16 (u, reg, status | (1 << 3) | VAS_EBOOT_UHCI_REG_PORTSC_CONNECT_CHANGED);
|
||||
VasEBoot_uhci_readreg16 (u, reg); /* Ensure it is writen... */
|
||||
|
||||
/* Enable the port. */
|
||||
status = VasEBoot_uhci_readreg16 (u, reg) & ~VAS_EBOOT_UHCI_PORTSC_RWC;
|
||||
VasEBoot_uhci_writereg16 (u, reg, status | (1 << 2));
|
||||
VasEBoot_uhci_readreg16 (u, reg); /* Ensure it is writen... */
|
||||
|
||||
endtime = VasEBoot_get_time_ms () + 1000;
|
||||
while (! ((status = VasEBoot_uhci_readreg16 (u, reg)) & (1 << 2)))
|
||||
if (VasEBoot_get_time_ms () > endtime)
|
||||
return VAS_EBOOT_USB_ERR_TIMEOUT;
|
||||
|
||||
/* Reset recovery time */
|
||||
VasEBoot_millisleep (10);
|
||||
|
||||
/* Read final port status */
|
||||
status = VasEBoot_uhci_readreg16 (u, reg);
|
||||
VasEBoot_dprintf ("uhci", ">3detect=0x%02x\n", status);
|
||||
|
||||
|
||||
return VAS_EBOOT_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_usb_speed_t
|
||||
VasEBoot_uhci_detect_dev (VasEBoot_usb_controller_t dev, int port, int *changed)
|
||||
{
|
||||
struct VasEBoot_uhci *u = (struct VasEBoot_uhci *) dev->data;
|
||||
int reg;
|
||||
unsigned int status;
|
||||
|
||||
VasEBoot_dprintf ("uhci", "detect_dev, iobase:%08x\n", u->iobase);
|
||||
|
||||
if (port == 0)
|
||||
reg = VAS_EBOOT_UHCI_REG_PORTSC1;
|
||||
else if (port == 1)
|
||||
reg = VAS_EBOOT_UHCI_REG_PORTSC2;
|
||||
else
|
||||
return VAS_EBOOT_USB_SPEED_NONE;
|
||||
|
||||
status = VasEBoot_uhci_readreg16 (u, reg);
|
||||
|
||||
VasEBoot_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port);
|
||||
|
||||
/* Connect Status Change bit - it detects change of connection */
|
||||
if (status & VAS_EBOOT_UHCI_DETECT_CHANGED)
|
||||
{
|
||||
*changed = 1;
|
||||
/* Reset bit Connect Status Change */
|
||||
VasEBoot_uhci_writereg16 (u, reg, (status & VAS_EBOOT_UHCI_REG_PORTSC_RW)
|
||||
| VAS_EBOOT_UHCI_REG_PORTSC_CONNECT_CHANGED);
|
||||
}
|
||||
else
|
||||
*changed = 0;
|
||||
|
||||
if (! (status & VAS_EBOOT_UHCI_DETECT_HAVE_DEVICE))
|
||||
return VAS_EBOOT_USB_SPEED_NONE;
|
||||
else if (status & VAS_EBOOT_UHCI_DETECT_LOW_SPEED)
|
||||
return VAS_EBOOT_USB_SPEED_LOW;
|
||||
else
|
||||
return VAS_EBOOT_USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
static int
|
||||
VasEBoot_uhci_hubports (VasEBoot_usb_controller_t dev __attribute__((unused)))
|
||||
{
|
||||
/* The root hub has exactly two ports. */
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static struct VasEBoot_usb_controller_dev usb_controller =
|
||||
{
|
||||
.name = "uhci",
|
||||
.iterate = VasEBoot_uhci_iterate,
|
||||
.setup_transfer = VasEBoot_uhci_setup_transfer,
|
||||
.check_transfer = VasEBoot_uhci_check_transfer,
|
||||
.cancel_transfer = VasEBoot_uhci_cancel_transfer,
|
||||
.hubports = VasEBoot_uhci_hubports,
|
||||
.portstatus = VasEBoot_uhci_portstatus,
|
||||
.detect_dev = VasEBoot_uhci_detect_dev,
|
||||
/* estimated max. count of TDs for one bulk transfer */
|
||||
.max_bulk_tds = N_TD * 3 / 4
|
||||
};
|
||||
|
||||
VAS_EBOOT_MOD_INIT(uhci)
|
||||
{
|
||||
VasEBoot_stop_disk_firmware ();
|
||||
|
||||
VasEBoot_uhci_inithw ();
|
||||
VasEBoot_usb_controller_dev_register (&usb_controller);
|
||||
VasEBoot_dprintf ("uhci", "registered\n");
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(uhci)
|
||||
{
|
||||
struct VasEBoot_uhci *u;
|
||||
|
||||
/* Disable all UHCI controllers. */
|
||||
for (u = uhci; u; u = u->next)
|
||||
VasEBoot_uhci_writereg16 (u, VAS_EBOOT_UHCI_REG_USBCMD, 0);
|
||||
|
||||
/* Unregister the controller. */
|
||||
VasEBoot_usb_controller_dev_unregister (&usb_controller);
|
||||
}
|
||||
|
|
@ -0,0 +1,346 @@
|
|||
/* usb.c - Generic USB interfaces. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/list.h>
|
||||
#include <VasEBoot/term.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static struct VasEBoot_usb_attach_desc *attach_hooks;
|
||||
|
||||
#if 0
|
||||
/* Context for VasEBoot_usb_controller_iterate. */
|
||||
struct VasEBoot_usb_controller_iterate_ctx
|
||||
{
|
||||
VasEBoot_usb_controller_iterate_hook_t hook;
|
||||
void *hook_data;
|
||||
VasEBoot_usb_controller_dev_t p;
|
||||
};
|
||||
|
||||
/* Helper for VasEBoot_usb_controller_iterate. */
|
||||
static int
|
||||
VasEBoot_usb_controller_iterate_iter (VasEBoot_usb_controller_t dev, void *data)
|
||||
{
|
||||
struct VasEBoot_usb_controller_iterate_ctx *ctx = data;
|
||||
|
||||
dev->dev = ctx->p;
|
||||
if (ctx->hook (dev, ctx->hook_data))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
VasEBoot_usb_controller_iterate (VasEBoot_usb_controller_iterate_hook_t hook,
|
||||
void *hook_data)
|
||||
{
|
||||
struct VasEBoot_usb_controller_iterate_ctx ctx = {
|
||||
.hook = hook,
|
||||
.hook_data = hook_data
|
||||
};
|
||||
|
||||
/* Iterate over all controller drivers. */
|
||||
for (ctx.p = VasEBoot_usb_list; ctx.p; ctx.p = ctx.p->next)
|
||||
{
|
||||
/* Iterate over the busses of the controllers. XXX: Actually, a
|
||||
hub driver should do this. */
|
||||
if (ctx.p->iterate (VasEBoot_usb_controller_iterate_iter, &ctx))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_clear_halt (VasEBoot_usb_device_t dev, int endpoint)
|
||||
{
|
||||
if (endpoint >= VAS_EBOOT_USB_MAX_TOGGLE)
|
||||
return VAS_EBOOT_USB_ERR_BADDEVICE;
|
||||
|
||||
dev->toggle[endpoint] = 0;
|
||||
return VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_STANDARD
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_ENDP),
|
||||
VAS_EBOOT_USB_REQ_CLEAR_FEATURE,
|
||||
VAS_EBOOT_USB_FEATURE_ENDP_HALT,
|
||||
endpoint, 0, 0);
|
||||
}
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_set_configuration (VasEBoot_usb_device_t dev, int configuration)
|
||||
{
|
||||
VasEBoot_memset (dev->toggle, 0, sizeof (dev->toggle));
|
||||
|
||||
return VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_STANDARD
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_DEV),
|
||||
VAS_EBOOT_USB_REQ_SET_CONFIGURATION, configuration,
|
||||
0, 0, NULL);
|
||||
}
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_get_descriptor (VasEBoot_usb_device_t dev,
|
||||
VasEBoot_uint8_t type, VasEBoot_uint8_t index,
|
||||
VasEBoot_size_t size, char *data)
|
||||
{
|
||||
return VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_IN
|
||||
| VAS_EBOOT_USB_REQTYPE_STANDARD
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_DEV),
|
||||
VAS_EBOOT_USB_REQ_GET_DESCRIPTOR,
|
||||
(type << 8) | index,
|
||||
0, size, data);
|
||||
}
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_device_initialize (VasEBoot_usb_device_t dev)
|
||||
{
|
||||
struct VasEBoot_usb_desc_device *descdev;
|
||||
struct VasEBoot_usb_desc_config config;
|
||||
VasEBoot_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 = VasEBoot_usb_get_descriptor (dev, VAS_EBOOT_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 = VasEBoot_usb_get_descriptor (dev, VAS_EBOOT_USB_DESCRIPTOR_DEVICE,
|
||||
0, sizeof (struct VasEBoot_usb_desc_device),
|
||||
(char *) &dev->descdev);
|
||||
if (err)
|
||||
return err;
|
||||
descdev = &dev->descdev;
|
||||
|
||||
for (i = 0; i < VAS_EBOOT_USB_MAX_CONF; i++)
|
||||
dev->config[i].descconf = NULL;
|
||||
|
||||
if (descdev->configcnt == 0 || descdev->configcnt > VAS_EBOOT_USB_MAX_CONF)
|
||||
{
|
||||
err = VAS_EBOOT_USB_ERR_BADDEVICE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < descdev->configcnt; i++)
|
||||
{
|
||||
int pos;
|
||||
int currif;
|
||||
char *data;
|
||||
struct VasEBoot_usb_desc *desc;
|
||||
|
||||
/* First just read the first 4 bytes of the configuration
|
||||
descriptor, after that it is known how many bytes really have
|
||||
to be read. */
|
||||
err = VasEBoot_usb_get_descriptor (dev, VAS_EBOOT_USB_DESCRIPTOR_CONFIG, i, 4,
|
||||
(char *) &config);
|
||||
|
||||
data = VasEBoot_malloc (config.totallen);
|
||||
if (! data)
|
||||
{
|
||||
err = VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev->config[i].descconf = (struct VasEBoot_usb_desc_config *) data;
|
||||
err = VasEBoot_usb_get_descriptor (dev, VAS_EBOOT_USB_DESCRIPTOR_CONFIG, i,
|
||||
config.totallen, data);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
/* Skip the configuration descriptor. */
|
||||
pos = dev->config[i].descconf->length;
|
||||
|
||||
if (dev->config[i].descconf->numif > VAS_EBOOT_USB_MAX_IF)
|
||||
{
|
||||
err = VAS_EBOOT_USB_ERR_BADDEVICE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Read all interfaces. */
|
||||
for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
|
||||
{
|
||||
while (pos < config.totallen)
|
||||
{
|
||||
desc = (struct VasEBoot_usb_desc *)&data[pos];
|
||||
if (desc->type == VAS_EBOOT_USB_DESCRIPTOR_INTERFACE)
|
||||
break;
|
||||
if (!desc->length)
|
||||
{
|
||||
err = VAS_EBOOT_USB_ERR_BADDEVICE;
|
||||
goto fail;
|
||||
}
|
||||
pos += desc->length;
|
||||
}
|
||||
|
||||
dev->config[i].interf[currif].descif
|
||||
= (struct VasEBoot_usb_desc_if *) &data[pos];
|
||||
pos += dev->config[i].interf[currif].descif->length;
|
||||
|
||||
while (pos < config.totallen)
|
||||
{
|
||||
desc = (struct VasEBoot_usb_desc *)&data[pos];
|
||||
if (desc->type == VAS_EBOOT_USB_DESCRIPTOR_ENDPOINT)
|
||||
break;
|
||||
if (!desc->length)
|
||||
{
|
||||
err = VAS_EBOOT_USB_ERR_BADDEVICE;
|
||||
goto fail;
|
||||
}
|
||||
pos += desc->length;
|
||||
}
|
||||
|
||||
/* Point to the first endpoint. */
|
||||
dev->config[i].interf[currif].descendp
|
||||
= (struct VasEBoot_usb_desc_endp *) &data[pos];
|
||||
pos += (sizeof (struct VasEBoot_usb_desc_endp)
|
||||
* dev->config[i].interf[currif].descif->endpointcnt);
|
||||
}
|
||||
}
|
||||
|
||||
return VAS_EBOOT_USB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
|
||||
for (i = 0; i < VAS_EBOOT_USB_MAX_CONF; i++)
|
||||
VasEBoot_free (dev->config[i].descconf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void VasEBoot_usb_device_attach (VasEBoot_usb_device_t dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* XXX: Just check configuration 0 for now. */
|
||||
for (i = 0; i < dev->config[0].descconf->numif; i++)
|
||||
{
|
||||
struct VasEBoot_usb_desc_if *interf;
|
||||
struct VasEBoot_usb_attach_desc *desc;
|
||||
|
||||
interf = dev->config[0].interf[i].descif;
|
||||
|
||||
VasEBoot_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)
|
||||
{
|
||||
VasEBoot_boot_time ("Probing USB device driver class %x", desc->class);
|
||||
if (desc->hook (dev, 0, i))
|
||||
dev->config[0].interf[i].attached = 1;
|
||||
VasEBoot_boot_time ("Probed USB device driver class %x", desc->class);
|
||||
}
|
||||
|
||||
if (dev->config[0].interf[i].attached)
|
||||
continue;
|
||||
|
||||
switch (interf->class)
|
||||
{
|
||||
case VAS_EBOOT_USB_CLASS_MASS_STORAGE:
|
||||
VasEBoot_dl_load ("usbms");
|
||||
VasEBoot_print_error ();
|
||||
break;
|
||||
case VAS_EBOOT_USB_CLASS_HID:
|
||||
VasEBoot_dl_load ("usb_keyboard");
|
||||
VasEBoot_print_error ();
|
||||
break;
|
||||
case 0xff:
|
||||
/* FIXME: don't load useless modules. */
|
||||
VasEBoot_dl_load ("usbserial_ftdi");
|
||||
VasEBoot_print_error ();
|
||||
VasEBoot_dl_load ("usbserial_pl2303");
|
||||
VasEBoot_print_error ();
|
||||
VasEBoot_dl_load ("usbserial_usbdebug");
|
||||
VasEBoot_print_error ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for VasEBoot_usb_register_attach_hook_class. */
|
||||
static int
|
||||
VasEBoot_usb_register_attach_hook_class_iter (VasEBoot_usb_device_t usbdev, void *data)
|
||||
{
|
||||
struct VasEBoot_usb_attach_desc *desc = data;
|
||||
struct VasEBoot_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 VasEBoot_usb_desc_if *interf;
|
||||
|
||||
interf = usbdev->config[0].interf[i].descif;
|
||||
|
||||
VasEBoot_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;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_usb_register_attach_hook_class (struct VasEBoot_usb_attach_desc *desc)
|
||||
{
|
||||
desc->next = attach_hooks;
|
||||
attach_hooks = desc;
|
||||
|
||||
VasEBoot_usb_iterate (VasEBoot_usb_register_attach_hook_class_iter, desc);
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_usb_unregister_attach_hook_class (struct VasEBoot_usb_attach_desc *desc)
|
||||
{
|
||||
VasEBoot_list_remove (VAS_EBOOT_AS_LIST (desc));
|
||||
}
|
||||
|
||||
|
||||
VAS_EBOOT_MOD_INIT(usb)
|
||||
{
|
||||
VasEBoot_term_poll_usb = VasEBoot_usb_poll_devices;
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(usb)
|
||||
{
|
||||
VasEBoot_term_poll_usb = NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,756 @@
|
|||
/* usb.c - USB Hub Support. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/time.h>
|
||||
|
||||
#define VAS_EBOOT_USBHUB_MAX_DEVICES 128
|
||||
|
||||
/* USB Supports 127 devices, with device 0 as special case. */
|
||||
static struct VasEBoot_usb_device *VasEBoot_usb_devs[VAS_EBOOT_USBHUB_MAX_DEVICES];
|
||||
|
||||
static int rescan = 0;
|
||||
static int npending = 0;
|
||||
|
||||
struct VasEBoot_usb_hub
|
||||
{
|
||||
struct VasEBoot_usb_hub *next;
|
||||
VasEBoot_usb_controller_t controller;
|
||||
int nports;
|
||||
struct VasEBoot_usb_device **devices;
|
||||
struct VasEBoot_usb_hub_port *ports;
|
||||
VasEBoot_usb_device_t dev;
|
||||
};
|
||||
|
||||
static struct VasEBoot_usb_hub *hubs;
|
||||
static VasEBoot_usb_controller_dev_t VasEBoot_usb_list;
|
||||
|
||||
/* Add a device that currently has device number 0 and resides on
|
||||
CONTROLLER, the Hub reported that the device speed is SPEED. */
|
||||
static VasEBoot_usb_device_t
|
||||
VasEBoot_usb_hub_add_dev (VasEBoot_usb_controller_t controller,
|
||||
VasEBoot_usb_speed_t speed,
|
||||
int split_hubport, int split_hubaddr)
|
||||
{
|
||||
VasEBoot_usb_device_t dev;
|
||||
int i;
|
||||
VasEBoot_usb_err_t err;
|
||||
|
||||
VasEBoot_boot_time ("Attaching USB device");
|
||||
|
||||
dev = VasEBoot_zalloc (sizeof (struct VasEBoot_usb_device));
|
||||
if (! dev)
|
||||
return NULL;
|
||||
|
||||
dev->controller = *controller;
|
||||
dev->speed = speed;
|
||||
dev->split_hubport = split_hubport;
|
||||
dev->split_hubaddr = split_hubaddr;
|
||||
|
||||
err = VasEBoot_usb_device_initialize (dev);
|
||||
if (err)
|
||||
{
|
||||
VasEBoot_free (dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Assign a new address to the device. */
|
||||
for (i = 1; i < VAS_EBOOT_USBHUB_MAX_DEVICES; i++)
|
||||
{
|
||||
if (! VasEBoot_usb_devs[i])
|
||||
break;
|
||||
}
|
||||
if (i == VAS_EBOOT_USBHUB_MAX_DEVICES)
|
||||
{
|
||||
VasEBoot_error (VAS_EBOOT_ERR_IO, "can't assign address to USB device");
|
||||
for (i = 0; i < VAS_EBOOT_USB_MAX_CONF; i++)
|
||||
VasEBoot_free (dev->config[i].descconf);
|
||||
VasEBoot_free (dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = VasEBoot_usb_control_msg (dev,
|
||||
(VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_STANDARD
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_DEV),
|
||||
VAS_EBOOT_USB_REQ_SET_ADDRESS,
|
||||
i, 0, 0, NULL);
|
||||
if (err)
|
||||
{
|
||||
for (i = 0; i < VAS_EBOOT_USB_MAX_CONF; i++)
|
||||
VasEBoot_free (dev->config[i].descconf);
|
||||
VasEBoot_free (dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev->addr = i;
|
||||
dev->initialized = 1;
|
||||
VasEBoot_usb_devs[i] = dev;
|
||||
|
||||
VasEBoot_dprintf ("usb", "Added new usb device: %p, addr=%d\n",
|
||||
dev, i);
|
||||
VasEBoot_dprintf ("usb", "speed=%d, split_hubport=%d, split_hubaddr=%d\n",
|
||||
speed, split_hubport, split_hubaddr);
|
||||
|
||||
/* Wait "recovery interval", spec. says 2ms */
|
||||
VasEBoot_millisleep (2);
|
||||
|
||||
VasEBoot_boot_time ("Probing USB device driver");
|
||||
|
||||
VasEBoot_usb_device_attach (dev);
|
||||
|
||||
VasEBoot_boot_time ("Attached USB device");
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static VasEBoot_usb_err_t
|
||||
VasEBoot_usb_add_hub (VasEBoot_usb_device_t dev)
|
||||
{
|
||||
struct VasEBoot_usb_usb_hubdesc hubdesc;
|
||||
VasEBoot_usb_err_t err;
|
||||
int i;
|
||||
|
||||
err = VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_IN
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_DEV),
|
||||
VAS_EBOOT_USB_REQ_GET_DESCRIPTOR,
|
||||
(VAS_EBOOT_USB_DESCRIPTOR_HUB << 8) | 0,
|
||||
0, sizeof (hubdesc), (char *) &hubdesc);
|
||||
if (err)
|
||||
return err;
|
||||
VasEBoot_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. */
|
||||
VasEBoot_dprintf ("usb", "Hub set configuration\n");
|
||||
VasEBoot_usb_set_configuration (dev, 1);
|
||||
|
||||
dev->nports = hubdesc.portcnt;
|
||||
dev->children = VasEBoot_calloc (hubdesc.portcnt, sizeof (dev->children[0]));
|
||||
dev->ports = VasEBoot_calloc (dev->nports, sizeof (dev->ports[0]));
|
||||
if (!dev->children || !dev->ports)
|
||||
{
|
||||
VasEBoot_free (dev->children);
|
||||
VasEBoot_free (dev->ports);
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Power on all Hub ports. */
|
||||
for (i = 1; i <= hubdesc.portcnt; i++)
|
||||
{
|
||||
VasEBoot_dprintf ("usb", "Power on - port %d\n", i);
|
||||
/* Power on the port and wait for possible device connect */
|
||||
VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_SET_FEATURE,
|
||||
VAS_EBOOT_USB_HUB_FEATURE_PORT_POWER,
|
||||
i, 0, NULL);
|
||||
}
|
||||
|
||||
/* Rest will be done on next usb poll. */
|
||||
for (i = 0; i < dev->config[0].interf[0].descif->endpointcnt;
|
||||
i++)
|
||||
{
|
||||
struct VasEBoot_usb_desc_endp *endp = NULL;
|
||||
endp = &dev->config[0].interf[0].descendp[i];
|
||||
|
||||
if ((endp->endp_addr & 128) && VasEBoot_usb_get_ep_type(endp)
|
||||
== VAS_EBOOT_USB_EP_INTERRUPT)
|
||||
{
|
||||
VasEBoot_size_t len;
|
||||
dev->hub_endpoint = endp;
|
||||
len = endp->maxpacket;
|
||||
if (len > sizeof (dev->statuschange))
|
||||
len = sizeof (dev->statuschange);
|
||||
dev->hub_transfer
|
||||
= VasEBoot_usb_bulk_read_background (dev, endp, len,
|
||||
(char *) &dev->statuschange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rescan = 1;
|
||||
|
||||
return VAS_EBOOT_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
attach_root_port (struct VasEBoot_usb_hub *hub, int portno,
|
||||
VasEBoot_usb_speed_t speed)
|
||||
{
|
||||
VasEBoot_usb_device_t dev;
|
||||
VasEBoot_usb_err_t err;
|
||||
|
||||
VasEBoot_boot_time ("After detect_dev");
|
||||
|
||||
/* Enable the port. */
|
||||
err = hub->controller->dev->portstatus (hub->controller, portno, 1);
|
||||
if (err)
|
||||
return;
|
||||
hub->controller->dev->pending_reset = VasEBoot_get_time_ms () + 5000;
|
||||
npending++;
|
||||
|
||||
VasEBoot_millisleep (10);
|
||||
|
||||
VasEBoot_boot_time ("Port enabled");
|
||||
|
||||
/* Enable the port and create a device. */
|
||||
/* High speed device needs not transaction translation
|
||||
and full/low speed device cannot be connected to EHCI root hub
|
||||
and full/low speed device connected to OHCI/UHCI needs not
|
||||
transaction translation - e.g. hubport and hubaddr should be
|
||||
always none (zero) for any device connected to any root hub. */
|
||||
dev = VasEBoot_usb_hub_add_dev (hub->controller, speed, 0, 0);
|
||||
hub->controller->dev->pending_reset = 0;
|
||||
npending--;
|
||||
if (! dev)
|
||||
return;
|
||||
|
||||
hub->devices[portno] = dev;
|
||||
|
||||
/* If the device is a Hub, scan it for more devices. */
|
||||
if (dev->descdev.class == 0x09)
|
||||
VasEBoot_usb_add_hub (dev);
|
||||
|
||||
VasEBoot_boot_time ("Attached root port");
|
||||
}
|
||||
|
||||
/* Iterate over all controllers found by the driver. */
|
||||
static int
|
||||
VasEBoot_usb_controller_dev_register_iter (VasEBoot_usb_controller_t controller, void *data)
|
||||
{
|
||||
VasEBoot_usb_controller_dev_t usb = data;
|
||||
struct VasEBoot_usb_hub *hub;
|
||||
|
||||
controller->dev = usb;
|
||||
|
||||
VasEBoot_boot_time ("Registering USB root hub");
|
||||
|
||||
hub = VasEBoot_malloc (sizeof (*hub));
|
||||
if (!hub)
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
|
||||
hub->next = hubs;
|
||||
hubs = hub;
|
||||
hub->controller = VasEBoot_malloc (sizeof (*controller));
|
||||
if (!hub->controller)
|
||||
{
|
||||
VasEBoot_free (hub);
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
VasEBoot_memcpy (hub->controller, controller, sizeof (*controller));
|
||||
hub->dev = 0;
|
||||
|
||||
/* Query the number of ports the root Hub has. */
|
||||
hub->nports = controller->dev->hubports (controller);
|
||||
hub->devices = VasEBoot_calloc (hub->nports, sizeof (hub->devices[0]));
|
||||
hub->ports = VasEBoot_calloc (hub->nports, sizeof (hub->ports[0]));
|
||||
if (!hub->devices || !hub->ports)
|
||||
{
|
||||
VasEBoot_free (hub->devices);
|
||||
VasEBoot_free (hub->ports);
|
||||
VasEBoot_free (hub->controller);
|
||||
VasEBoot_free (hub);
|
||||
VasEBoot_print_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_usb_controller_dev_unregister (VasEBoot_usb_controller_dev_t usb)
|
||||
{
|
||||
VasEBoot_usb_controller_dev_t *p, q;
|
||||
|
||||
for (p = &VasEBoot_usb_list, q = *p; q; p = &(q->next), q = q->next)
|
||||
if (q == usb)
|
||||
{
|
||||
*p = q->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_usb_controller_dev_register (VasEBoot_usb_controller_dev_t usb)
|
||||
{
|
||||
int portno;
|
||||
int continue_waiting = 0;
|
||||
struct VasEBoot_usb_hub *hub;
|
||||
|
||||
usb->next = VasEBoot_usb_list;
|
||||
VasEBoot_usb_list = usb;
|
||||
|
||||
if (usb->iterate)
|
||||
usb->iterate (VasEBoot_usb_controller_dev_register_iter, usb);
|
||||
|
||||
VasEBoot_boot_time ("waiting for stable power on USB root\n");
|
||||
|
||||
while (1)
|
||||
{
|
||||
for (hub = hubs; hub; hub = hub->next)
|
||||
if (hub->controller->dev == usb)
|
||||
{
|
||||
/* Wait for completion of insertion and stable power (USB spec.)
|
||||
* Should be at least 100ms, some devices requires more...
|
||||
* There is also another thing - some devices have worse contacts
|
||||
* and connected signal is unstable for some time - we should handle
|
||||
* it - but prevent deadlock in case when device is too faulty... */
|
||||
for (portno = 0; portno < hub->nports; portno++)
|
||||
{
|
||||
VasEBoot_usb_speed_t speed;
|
||||
int changed = 0;
|
||||
|
||||
speed = hub->controller->dev->detect_dev (hub->controller, portno,
|
||||
&changed);
|
||||
|
||||
if (hub->ports[portno].state == PORT_STATE_NORMAL
|
||||
&& speed != VAS_EBOOT_USB_SPEED_NONE)
|
||||
{
|
||||
hub->ports[portno].soft_limit_time = VasEBoot_get_time_ms () + 250;
|
||||
hub->ports[portno].hard_limit_time = hub->ports[portno].soft_limit_time + 1750;
|
||||
hub->ports[portno].state = PORT_STATE_WAITING_FOR_STABLE_POWER;
|
||||
VasEBoot_boot_time ("Scheduling stable power wait for port %p:%d",
|
||||
usb, portno);
|
||||
continue_waiting++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER
|
||||
&& speed == VAS_EBOOT_USB_SPEED_NONE)
|
||||
{
|
||||
hub->ports[portno].soft_limit_time = VasEBoot_get_time_ms () + 250;
|
||||
continue;
|
||||
}
|
||||
if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER
|
||||
&& VasEBoot_get_time_ms () > hub->ports[portno].soft_limit_time)
|
||||
{
|
||||
hub->ports[portno].state = PORT_STATE_STABLE_POWER;
|
||||
VasEBoot_boot_time ("Got stable power wait for port %p:%d",
|
||||
usb, portno);
|
||||
continue_waiting--;
|
||||
continue;
|
||||
}
|
||||
if (hub->ports[portno].state == PORT_STATE_WAITING_FOR_STABLE_POWER
|
||||
&& VasEBoot_get_time_ms () > hub->ports[portno].hard_limit_time)
|
||||
{
|
||||
hub->ports[portno].state = PORT_STATE_FAILED_DEVICE;
|
||||
continue_waiting--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!continue_waiting)
|
||||
break;
|
||||
VasEBoot_millisleep (1);
|
||||
}
|
||||
|
||||
VasEBoot_boot_time ("After the stable power wait on USB root");
|
||||
|
||||
for (hub = hubs; hub; hub = hub->next)
|
||||
if (hub->controller->dev == usb)
|
||||
for (portno = 0; portno < hub->nports; portno++)
|
||||
if (hub->ports[portno].state == PORT_STATE_STABLE_POWER)
|
||||
{
|
||||
VasEBoot_usb_speed_t speed;
|
||||
int changed = 0;
|
||||
hub->ports[portno].state = PORT_STATE_NORMAL;
|
||||
speed = hub->controller->dev->detect_dev (hub->controller, portno, &changed);
|
||||
attach_root_port (hub, portno, speed);
|
||||
}
|
||||
|
||||
VasEBoot_boot_time ("USB root hub registered");
|
||||
}
|
||||
|
||||
static void detach_device (VasEBoot_usb_device_t dev);
|
||||
|
||||
static void
|
||||
detach_device (VasEBoot_usb_device_t dev)
|
||||
{
|
||||
unsigned i;
|
||||
int k;
|
||||
if (!dev)
|
||||
return;
|
||||
if (dev->descdev.class == VAS_EBOOT_USB_CLASS_HUB)
|
||||
{
|
||||
if (dev->hub_transfer)
|
||||
VasEBoot_usb_cancel_transfer (dev->hub_transfer);
|
||||
|
||||
for (i = 0; i < dev->nports; i++)
|
||||
detach_device (dev->children[i]);
|
||||
VasEBoot_free (dev->children);
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE (dev->config); i++)
|
||||
if (dev->config[i].descconf)
|
||||
for (k = 0; k < dev->config[i].descconf->numif; k++)
|
||||
{
|
||||
struct VasEBoot_usb_interface *inter = &dev->config[i].interf[k];
|
||||
if (inter && inter->detach_hook)
|
||||
inter->detach_hook (dev, i, k);
|
||||
}
|
||||
VasEBoot_usb_devs[dev->addr] = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
wait_power_nonroot_hub (VasEBoot_usb_device_t dev)
|
||||
{
|
||||
VasEBoot_usb_err_t err;
|
||||
int continue_waiting = 0;
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i <= dev->nports; i++)
|
||||
if (dev->ports[i - 1].state == PORT_STATE_WAITING_FOR_STABLE_POWER)
|
||||
{
|
||||
VasEBoot_uint64_t tm;
|
||||
VasEBoot_uint32_t current_status = 0;
|
||||
|
||||
/* Get the port status. */
|
||||
err = VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_IN
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_GET_STATUS,
|
||||
0, i,
|
||||
sizeof (current_status),
|
||||
(char *) ¤t_status);
|
||||
if (err)
|
||||
{
|
||||
dev->ports[i - 1].state = PORT_STATE_FAILED_DEVICE;
|
||||
continue;
|
||||
}
|
||||
tm = VasEBoot_get_time_ms ();
|
||||
if (!(current_status & VAS_EBOOT_USB_HUB_STATUS_PORT_CONNECTED))
|
||||
dev->ports[i - 1].soft_limit_time = tm + 250;
|
||||
if (tm >= dev->ports[i - 1].soft_limit_time)
|
||||
{
|
||||
if (dev->controller.dev->pending_reset)
|
||||
continue;
|
||||
/* Now do reset of port. */
|
||||
VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_SET_FEATURE,
|
||||
VAS_EBOOT_USB_HUB_FEATURE_PORT_RESET,
|
||||
i, 0, 0);
|
||||
dev->ports[i - 1].state = PORT_STATE_NORMAL;
|
||||
VasEBoot_boot_time ("Resetting port %p:%d", dev, i - 1);
|
||||
|
||||
rescan = 1;
|
||||
/* We cannot reset more than one device at the same time !
|
||||
* Resetting more devices together results in very bad
|
||||
* situation: more than one device has default address 0
|
||||
* at the same time !!!
|
||||
* Additionaly, we cannot perform another reset
|
||||
* anywhere on the same OHCI controller until
|
||||
* we will finish addressing of reseted device ! */
|
||||
dev->controller.dev->pending_reset = VasEBoot_get_time_ms () + 5000;
|
||||
npending++;
|
||||
continue;
|
||||
}
|
||||
if (tm >= dev->ports[i - 1].hard_limit_time)
|
||||
{
|
||||
dev->ports[i - 1].state = PORT_STATE_FAILED_DEVICE;
|
||||
continue;
|
||||
}
|
||||
continue_waiting = 1;
|
||||
}
|
||||
return continue_waiting && dev->controller.dev->pending_reset == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
poll_nonroot_hub (VasEBoot_usb_device_t dev)
|
||||
{
|
||||
VasEBoot_usb_err_t err;
|
||||
unsigned i;
|
||||
VasEBoot_uint32_t changed;
|
||||
VasEBoot_size_t actual, len;
|
||||
|
||||
if (!dev->hub_transfer)
|
||||
return;
|
||||
|
||||
err = VasEBoot_usb_check_transfer (dev->hub_transfer, &actual);
|
||||
|
||||
if (err == VAS_EBOOT_USB_ERR_WAIT)
|
||||
return;
|
||||
|
||||
changed = dev->statuschange;
|
||||
|
||||
len = dev->hub_endpoint->maxpacket;
|
||||
if (len > sizeof (dev->statuschange))
|
||||
len = sizeof (dev->statuschange);
|
||||
dev->hub_transfer
|
||||
= VasEBoot_usb_bulk_read_background (dev, dev->hub_endpoint, len,
|
||||
(char *) &dev->statuschange);
|
||||
|
||||
if (err || actual == 0 || changed == 0)
|
||||
return;
|
||||
|
||||
/* Iterate over the Hub ports. */
|
||||
for (i = 1; i <= dev->nports; i++)
|
||||
{
|
||||
VasEBoot_uint32_t status;
|
||||
|
||||
if (!(changed & (1 << i))
|
||||
|| dev->ports[i - 1].state == PORT_STATE_WAITING_FOR_STABLE_POWER)
|
||||
continue;
|
||||
|
||||
/* Get the port status. */
|
||||
err = VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_IN
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
|
||||
VasEBoot_dprintf ("usb", "dev = %p, i = %d, status = %08x\n",
|
||||
dev, i, status);
|
||||
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
/* FIXME: properly handle these conditions. */
|
||||
if (status & VAS_EBOOT_USB_HUB_STATUS_C_PORT_ENABLED)
|
||||
VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_CLEAR_FEATURE,
|
||||
VAS_EBOOT_USB_HUB_FEATURE_C_PORT_ENABLED, i, 0, 0);
|
||||
|
||||
if (status & VAS_EBOOT_USB_HUB_STATUS_C_PORT_SUSPEND)
|
||||
VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_CLEAR_FEATURE,
|
||||
VAS_EBOOT_USB_HUB_FEATURE_C_PORT_SUSPEND, i, 0, 0);
|
||||
|
||||
if (status & VAS_EBOOT_USB_HUB_STATUS_C_PORT_OVERCURRENT)
|
||||
VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_CLEAR_FEATURE,
|
||||
VAS_EBOOT_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0);
|
||||
|
||||
if (!dev->controller.dev->pending_reset &&
|
||||
(status & VAS_EBOOT_USB_HUB_STATUS_C_PORT_CONNECTED))
|
||||
{
|
||||
VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_CLEAR_FEATURE,
|
||||
VAS_EBOOT_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0);
|
||||
|
||||
detach_device (dev->children[i - 1]);
|
||||
dev->children[i - 1] = NULL;
|
||||
|
||||
/* Connected and status of connection changed ? */
|
||||
if (status & VAS_EBOOT_USB_HUB_STATUS_PORT_CONNECTED)
|
||||
{
|
||||
VasEBoot_boot_time ("Before the stable power wait portno=%d", i);
|
||||
/* A device is actually connected to this port. */
|
||||
/* Wait for completion of insertion and stable power (USB spec.)
|
||||
* Should be at least 100ms, some devices requires more...
|
||||
* There is also another thing - some devices have worse contacts
|
||||
* and connected signal is unstable for some time - we should handle
|
||||
* it - but prevent deadlock in case when device is too faulty... */
|
||||
dev->ports[i - 1].soft_limit_time = VasEBoot_get_time_ms () + 250;
|
||||
dev->ports[i - 1].hard_limit_time = dev->ports[i - 1].soft_limit_time + 1750;
|
||||
dev->ports[i - 1].state = PORT_STATE_WAITING_FOR_STABLE_POWER;
|
||||
VasEBoot_boot_time ("Scheduling stable power wait for port %p:%d",
|
||||
dev, i - 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (status & VAS_EBOOT_USB_HUB_STATUS_C_PORT_RESET)
|
||||
{
|
||||
VasEBoot_usb_control_msg (dev, (VAS_EBOOT_USB_REQTYPE_OUT
|
||||
| VAS_EBOOT_USB_REQTYPE_CLASS
|
||||
| VAS_EBOOT_USB_REQTYPE_TARGET_OTHER),
|
||||
VAS_EBOOT_USB_REQ_CLEAR_FEATURE,
|
||||
VAS_EBOOT_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0);
|
||||
|
||||
VasEBoot_boot_time ("Port %d reset", i);
|
||||
|
||||
if (status & VAS_EBOOT_USB_HUB_STATUS_PORT_CONNECTED)
|
||||
{
|
||||
VasEBoot_usb_speed_t speed;
|
||||
VasEBoot_usb_device_t next_dev;
|
||||
int split_hubport = 0;
|
||||
int split_hubaddr = 0;
|
||||
|
||||
/* Determine the device speed. */
|
||||
if (status & VAS_EBOOT_USB_HUB_STATUS_PORT_LOWSPEED)
|
||||
speed = VAS_EBOOT_USB_SPEED_LOW;
|
||||
else
|
||||
{
|
||||
if (status & VAS_EBOOT_USB_HUB_STATUS_PORT_HIGHSPEED)
|
||||
speed = VAS_EBOOT_USB_SPEED_HIGH;
|
||||
else
|
||||
speed = VAS_EBOOT_USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
/* Wait a recovery time after reset, spec. says 10ms */
|
||||
VasEBoot_millisleep (10);
|
||||
|
||||
/* Find correct values for SPLIT hubport and hubaddr */
|
||||
if (speed == VAS_EBOOT_USB_SPEED_HIGH)
|
||||
{
|
||||
/* HIGH speed device needs not transaction translation */
|
||||
split_hubport = 0;
|
||||
split_hubaddr = 0;
|
||||
}
|
||||
else
|
||||
/* FULL/LOW device needs hub port and hub address
|
||||
for transaction translation (if connected to EHCI) */
|
||||
if (dev->speed == VAS_EBOOT_USB_SPEED_HIGH)
|
||||
{
|
||||
/* This port is the first FULL/LOW speed port
|
||||
in the chain from root hub. Attached device
|
||||
should use its port number and hub address */
|
||||
split_hubport = i;
|
||||
split_hubaddr = dev->addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This port is NOT the first FULL/LOW speed port
|
||||
in the chain from root hub. Attached device
|
||||
should use values inherited from some parent
|
||||
HIGH speed hub - if any. */
|
||||
split_hubport = dev->split_hubport;
|
||||
split_hubaddr = dev->split_hubaddr;
|
||||
}
|
||||
|
||||
/* Add the device and assign a device address to it. */
|
||||
next_dev = VasEBoot_usb_hub_add_dev (&dev->controller, speed,
|
||||
split_hubport, split_hubaddr);
|
||||
if (dev->controller.dev->pending_reset)
|
||||
{
|
||||
dev->controller.dev->pending_reset = 0;
|
||||
npending--;
|
||||
}
|
||||
if (! next_dev)
|
||||
continue;
|
||||
|
||||
dev->children[i - 1] = next_dev;
|
||||
|
||||
/* If the device is a Hub, scan it for more devices. */
|
||||
if (next_dev->descdev.class == 0x09)
|
||||
VasEBoot_usb_add_hub (next_dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_usb_poll_devices (int wait_for_completion)
|
||||
{
|
||||
struct VasEBoot_usb_hub *hub;
|
||||
int i;
|
||||
|
||||
for (hub = hubs; hub; hub = hub->next)
|
||||
{
|
||||
/* 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++)
|
||||
{
|
||||
VasEBoot_usb_speed_t speed = VAS_EBOOT_USB_SPEED_NONE;
|
||||
int changed = 0;
|
||||
|
||||
if (hub->controller->dev->pending_reset)
|
||||
{
|
||||
/* Check for possible timeout */
|
||||
if (VasEBoot_get_time_ms () > hub->controller->dev->pending_reset)
|
||||
{
|
||||
/* Something went wrong, reset device was not
|
||||
* addressed properly, timeout happened */
|
||||
hub->controller->dev->pending_reset = 0;
|
||||
npending--;
|
||||
}
|
||||
}
|
||||
if (!hub->controller->dev->pending_reset)
|
||||
speed = hub->controller->dev->detect_dev (hub->controller,
|
||||
i, &changed);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
detach_device (hub->devices[i]);
|
||||
hub->devices[i] = NULL;
|
||||
if (speed != VAS_EBOOT_USB_SPEED_NONE)
|
||||
attach_root_port (hub, i, speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
rescan = 0;
|
||||
|
||||
/* We should check changes of non-root hubs too. */
|
||||
for (i = 0; i < VAS_EBOOT_USBHUB_MAX_DEVICES; i++)
|
||||
{
|
||||
VasEBoot_usb_device_t dev = VasEBoot_usb_devs[i];
|
||||
|
||||
if (dev && dev->descdev.class == 0x09)
|
||||
poll_nonroot_hub (dev);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
int continue_waiting = 0;
|
||||
for (i = 0; i < VAS_EBOOT_USBHUB_MAX_DEVICES; i++)
|
||||
{
|
||||
VasEBoot_usb_device_t dev = VasEBoot_usb_devs[i];
|
||||
|
||||
if (dev && dev->descdev.class == 0x09)
|
||||
continue_waiting = continue_waiting || wait_power_nonroot_hub (dev);
|
||||
}
|
||||
if (!continue_waiting)
|
||||
break;
|
||||
VasEBoot_millisleep (1);
|
||||
}
|
||||
|
||||
if (!(rescan || (npending && wait_for_completion)))
|
||||
break;
|
||||
VasEBoot_millisleep (25);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
VasEBoot_usb_iterate (VasEBoot_usb_iterate_hook_t hook, void *hook_data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < VAS_EBOOT_USBHUB_MAX_DEVICES; i++)
|
||||
{
|
||||
if (VasEBoot_usb_devs[i])
|
||||
{
|
||||
if (hook (VasEBoot_usb_devs[i], hook_data))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,462 @@
|
|||
/* usbtrans.c - USB Transfers and Transactions. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/dma.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/usb.h>
|
||||
#include <VasEBoot/usbtrans.h>
|
||||
#include <VasEBoot/time.h>
|
||||
#include <VasEBoot/cache.h>
|
||||
|
||||
|
||||
static inline unsigned int
|
||||
VasEBoot_usb_bulk_maxpacket (VasEBoot_usb_device_t dev,
|
||||
struct VasEBoot_usb_desc_endp *endpoint)
|
||||
{
|
||||
/* Use the maximum packet size given in the endpoint descriptor. */
|
||||
if (dev->initialized && endpoint && (unsigned int) endpoint->maxpacket)
|
||||
return endpoint->maxpacket;
|
||||
|
||||
return 64;
|
||||
}
|
||||
|
||||
|
||||
static VasEBoot_usb_err_t
|
||||
VasEBoot_usb_execute_and_wait_transfer (VasEBoot_usb_device_t dev,
|
||||
VasEBoot_usb_transfer_t transfer,
|
||||
int timeout, VasEBoot_size_t *actual)
|
||||
{
|
||||
VasEBoot_usb_err_t err;
|
||||
VasEBoot_uint64_t endtime;
|
||||
|
||||
err = dev->controller.dev->setup_transfer (&dev->controller, transfer);
|
||||
if (err)
|
||||
return err;
|
||||
/* endtime moved behind setup transfer to prevent false timeouts
|
||||
* while debugging... */
|
||||
endtime = VasEBoot_get_time_ms () + timeout;
|
||||
while (1)
|
||||
{
|
||||
err = dev->controller.dev->check_transfer (&dev->controller, transfer,
|
||||
actual);
|
||||
if (!err)
|
||||
return VAS_EBOOT_USB_ERR_NONE;
|
||||
if (err != VAS_EBOOT_USB_ERR_WAIT)
|
||||
return err;
|
||||
if (VasEBoot_get_time_ms () > endtime)
|
||||
{
|
||||
err = dev->controller.dev->cancel_transfer (&dev->controller,
|
||||
transfer);
|
||||
if (err)
|
||||
return err;
|
||||
return VAS_EBOOT_USB_ERR_TIMEOUT;
|
||||
}
|
||||
VasEBoot_cpu_idle ();
|
||||
}
|
||||
}
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_control_msg (VasEBoot_usb_device_t dev,
|
||||
VasEBoot_uint8_t reqtype,
|
||||
VasEBoot_uint8_t request,
|
||||
VasEBoot_uint16_t value,
|
||||
VasEBoot_uint16_t index,
|
||||
VasEBoot_size_t size0, char *data_in)
|
||||
{
|
||||
int i;
|
||||
VasEBoot_usb_transfer_t transfer;
|
||||
int datablocks;
|
||||
volatile struct VasEBoot_usb_packet_setup *setupdata;
|
||||
VasEBoot_uint32_t setupdata_addr;
|
||||
VasEBoot_usb_err_t err;
|
||||
unsigned int max;
|
||||
struct VasEBoot_pci_dma_chunk *data_chunk, *setupdata_chunk;
|
||||
volatile char *data;
|
||||
VasEBoot_uint32_t data_addr;
|
||||
VasEBoot_size_t size = size0;
|
||||
VasEBoot_size_t actual;
|
||||
|
||||
/* FIXME: avoid allocation any kind of buffer in a first place. */
|
||||
data_chunk = VasEBoot_memalign_dma32 (128, size ? : 16);
|
||||
if (!data_chunk)
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
data = VasEBoot_dma_get_virt (data_chunk);
|
||||
data_addr = VasEBoot_dma_get_phys (data_chunk);
|
||||
VasEBoot_memcpy ((char *) data, data_in, size);
|
||||
|
||||
VasEBoot_arch_sync_dma_caches (data, size);
|
||||
|
||||
VasEBoot_dprintf ("usb",
|
||||
"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%lu\n",
|
||||
reqtype, request, value, index, (unsigned long)size);
|
||||
|
||||
/* Create a transfer. */
|
||||
transfer = VasEBoot_malloc (sizeof (*transfer));
|
||||
if (! transfer)
|
||||
{
|
||||
VasEBoot_dma_free (data_chunk);
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
setupdata_chunk = VasEBoot_memalign_dma32 (32, sizeof (*setupdata));
|
||||
if (! setupdata_chunk)
|
||||
{
|
||||
VasEBoot_free (transfer);
|
||||
VasEBoot_dma_free (data_chunk);
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
setupdata = VasEBoot_dma_get_virt (setupdata_chunk);
|
||||
setupdata_addr = VasEBoot_dma_get_phys (setupdata_chunk);
|
||||
|
||||
/* Determine the maximum packet size. */
|
||||
if (dev->descdev.maxsize0)
|
||||
max = dev->descdev.maxsize0;
|
||||
else
|
||||
max = 64;
|
||||
|
||||
VasEBoot_dprintf ("usb", "control: transfer = %p, dev = %p\n", transfer, dev);
|
||||
|
||||
datablocks = (size + max - 1) / max;
|
||||
|
||||
/* XXX: Discriminate between different types of control
|
||||
messages. */
|
||||
transfer->transcnt = datablocks + 2;
|
||||
transfer->size = size; /* XXX ? */
|
||||
transfer->endpoint = 0;
|
||||
transfer->devaddr = dev->addr;
|
||||
transfer->type = VAS_EBOOT_USB_TRANSACTION_TYPE_CONTROL;
|
||||
transfer->max = max;
|
||||
transfer->dev = dev;
|
||||
|
||||
/* Allocate an array of transfer data structures. */
|
||||
transfer->transactions = VasEBoot_malloc (transfer->transcnt
|
||||
* sizeof (struct VasEBoot_usb_transfer));
|
||||
if (! transfer->transactions)
|
||||
{
|
||||
VasEBoot_free (transfer);
|
||||
VasEBoot_dma_free (setupdata_chunk);
|
||||
VasEBoot_dma_free (data_chunk);
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Build a Setup packet. XXX: Endianness. */
|
||||
setupdata->reqtype = reqtype;
|
||||
setupdata->request = request;
|
||||
setupdata->value = value;
|
||||
setupdata->index = index;
|
||||
setupdata->length = size;
|
||||
VasEBoot_arch_sync_dma_caches (setupdata, sizeof (*setupdata));
|
||||
|
||||
transfer->transactions[0].size = sizeof (*setupdata);
|
||||
transfer->transactions[0].pid = VAS_EBOOT_USB_TRANSFER_TYPE_SETUP;
|
||||
transfer->transactions[0].data = setupdata_addr;
|
||||
transfer->transactions[0].toggle = 0;
|
||||
|
||||
/* Now the data... XXX: Is this the right way to transfer control
|
||||
transfers? */
|
||||
for (i = 0; i < datablocks; i++)
|
||||
{
|
||||
VasEBoot_usb_transaction_t tr = &transfer->transactions[i + 1];
|
||||
|
||||
tr->size = (size > max) ? max : size;
|
||||
/* Use the right most bit as the data toggle. Simple and
|
||||
effective. */
|
||||
tr->toggle = !(i & 1);
|
||||
if (reqtype & 128)
|
||||
tr->pid = VAS_EBOOT_USB_TRANSFER_TYPE_IN;
|
||||
else
|
||||
tr->pid = VAS_EBOOT_USB_TRANSFER_TYPE_OUT;
|
||||
tr->data = data_addr + i * max;
|
||||
tr->preceding = i * max;
|
||||
size -= max;
|
||||
}
|
||||
|
||||
/* End with an empty OUT transaction. */
|
||||
transfer->transactions[datablocks + 1].size = 0;
|
||||
transfer->transactions[datablocks + 1].data = 0;
|
||||
if ((reqtype & 128) && datablocks)
|
||||
transfer->transactions[datablocks + 1].pid = VAS_EBOOT_USB_TRANSFER_TYPE_OUT;
|
||||
else
|
||||
transfer->transactions[datablocks + 1].pid = VAS_EBOOT_USB_TRANSFER_TYPE_IN;
|
||||
|
||||
transfer->transactions[datablocks + 1].toggle = 1;
|
||||
|
||||
err = VasEBoot_usb_execute_and_wait_transfer (dev, transfer, 1000, &actual);
|
||||
|
||||
VasEBoot_dprintf ("usb", "control: err=%d\n", err);
|
||||
|
||||
VasEBoot_free (transfer->transactions);
|
||||
|
||||
VasEBoot_free (transfer);
|
||||
VasEBoot_dma_free (setupdata_chunk);
|
||||
|
||||
VasEBoot_arch_sync_dma_caches (data, size0);
|
||||
VasEBoot_memcpy (data_in, (char *) data, size0);
|
||||
|
||||
VasEBoot_dma_free (data_chunk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static VasEBoot_usb_transfer_t
|
||||
VasEBoot_usb_bulk_setup_readwrite (VasEBoot_usb_device_t dev,
|
||||
struct VasEBoot_usb_desc_endp *endpoint,
|
||||
VasEBoot_size_t size0, char *data_in,
|
||||
VasEBoot_transfer_type_t type)
|
||||
{
|
||||
int i;
|
||||
VasEBoot_usb_transfer_t transfer;
|
||||
int datablocks;
|
||||
unsigned int max;
|
||||
volatile char *data;
|
||||
VasEBoot_uint32_t data_addr;
|
||||
struct VasEBoot_pci_dma_chunk *data_chunk;
|
||||
VasEBoot_size_t size = size0;
|
||||
int toggle = dev->toggle[endpoint->endp_addr];
|
||||
|
||||
VasEBoot_dprintf ("usb", "bulk: size=0x%02lx type=%d\n", (unsigned long) size,
|
||||
type);
|
||||
|
||||
/* FIXME: avoid allocation any kind of buffer in a first place. */
|
||||
data_chunk = VasEBoot_memalign_dma32 (128, size);
|
||||
if (!data_chunk)
|
||||
return NULL;
|
||||
data = VasEBoot_dma_get_virt (data_chunk);
|
||||
data_addr = VasEBoot_dma_get_phys (data_chunk);
|
||||
if (type == VAS_EBOOT_USB_TRANSFER_TYPE_OUT)
|
||||
{
|
||||
VasEBoot_memcpy ((char *) data, data_in, size);
|
||||
VasEBoot_arch_sync_dma_caches (data, size);
|
||||
}
|
||||
|
||||
/* Create a transfer. */
|
||||
transfer = VasEBoot_malloc (sizeof (struct VasEBoot_usb_transfer));
|
||||
if (! transfer)
|
||||
{
|
||||
VasEBoot_dma_free (data_chunk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
max = VasEBoot_usb_bulk_maxpacket (dev, endpoint);
|
||||
|
||||
datablocks = ((size + max - 1) / max);
|
||||
transfer->transcnt = datablocks;
|
||||
transfer->size = size - 1;
|
||||
transfer->endpoint = endpoint->endp_addr;
|
||||
transfer->devaddr = dev->addr;
|
||||
transfer->type = VAS_EBOOT_USB_TRANSACTION_TYPE_BULK;
|
||||
transfer->dir = type;
|
||||
transfer->max = max;
|
||||
transfer->dev = dev;
|
||||
transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */
|
||||
transfer->data_chunk = data_chunk;
|
||||
transfer->data = data_in;
|
||||
|
||||
/* Allocate an array of transfer data structures. */
|
||||
transfer->transactions = VasEBoot_malloc (transfer->transcnt
|
||||
* sizeof (struct VasEBoot_usb_transfer));
|
||||
if (! transfer->transactions)
|
||||
{
|
||||
VasEBoot_free (transfer);
|
||||
VasEBoot_dma_free (data_chunk);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set up all transfers. */
|
||||
for (i = 0; i < datablocks; i++)
|
||||
{
|
||||
VasEBoot_usb_transaction_t tr = &transfer->transactions[i];
|
||||
|
||||
tr->size = (size > max) ? max : size;
|
||||
/* XXX: Use the right most bit as the data toggle. Simple and
|
||||
effective. */
|
||||
tr->toggle = toggle;
|
||||
toggle = toggle ? 0 : 1;
|
||||
tr->pid = type;
|
||||
tr->data = data_addr + i * max;
|
||||
tr->preceding = i * max;
|
||||
size -= tr->size;
|
||||
}
|
||||
return transfer;
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_usb_bulk_finish_readwrite (VasEBoot_usb_transfer_t transfer)
|
||||
{
|
||||
VasEBoot_usb_device_t dev = transfer->dev;
|
||||
int toggle = dev->toggle[transfer->endpoint];
|
||||
|
||||
/* 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[transfer->endpoint]; /* Nothing done, take original */
|
||||
VasEBoot_dprintf ("usb", "bulk: toggle=%d\n", toggle);
|
||||
dev->toggle[transfer->endpoint] = toggle;
|
||||
|
||||
if (transfer->dir == VAS_EBOOT_USB_TRANSFER_TYPE_IN)
|
||||
{
|
||||
VasEBoot_arch_sync_dma_caches (VasEBoot_dma_get_virt (transfer->data_chunk),
|
||||
transfer->size + 1);
|
||||
VasEBoot_memcpy (transfer->data, (void *)
|
||||
VasEBoot_dma_get_virt (transfer->data_chunk),
|
||||
transfer->size + 1);
|
||||
}
|
||||
|
||||
VasEBoot_free (transfer->transactions);
|
||||
VasEBoot_dma_free (transfer->data_chunk);
|
||||
VasEBoot_free (transfer);
|
||||
}
|
||||
|
||||
static VasEBoot_usb_err_t
|
||||
VasEBoot_usb_bulk_readwrite (VasEBoot_usb_device_t dev,
|
||||
struct VasEBoot_usb_desc_endp *endpoint,
|
||||
VasEBoot_size_t size0, char *data_in,
|
||||
VasEBoot_transfer_type_t type, int timeout,
|
||||
VasEBoot_size_t *actual)
|
||||
{
|
||||
VasEBoot_usb_err_t err;
|
||||
VasEBoot_usb_transfer_t transfer;
|
||||
|
||||
transfer = VasEBoot_usb_bulk_setup_readwrite (dev, endpoint, size0,
|
||||
data_in, type);
|
||||
if (!transfer)
|
||||
return VAS_EBOOT_USB_ERR_INTERNAL;
|
||||
err = VasEBoot_usb_execute_and_wait_transfer (dev, transfer, timeout, actual);
|
||||
|
||||
VasEBoot_usb_bulk_finish_readwrite (transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static VasEBoot_usb_err_t
|
||||
VasEBoot_usb_bulk_readwrite_packetize (VasEBoot_usb_device_t dev,
|
||||
struct VasEBoot_usb_desc_endp *endpoint,
|
||||
VasEBoot_transfer_type_t type,
|
||||
VasEBoot_size_t size, char *data)
|
||||
{
|
||||
VasEBoot_size_t actual, transferred;
|
||||
VasEBoot_usb_err_t err = VAS_EBOOT_USB_ERR_NONE;
|
||||
VasEBoot_size_t current_size, position;
|
||||
VasEBoot_size_t max_bulk_transfer_len = MAX_USB_TRANSFER_LEN;
|
||||
VasEBoot_size_t max;
|
||||
|
||||
if (dev->controller.dev->max_bulk_tds)
|
||||
{
|
||||
max = VasEBoot_usb_bulk_maxpacket (dev, endpoint);
|
||||
|
||||
/* Calculate max. possible length of bulk transfer */
|
||||
max_bulk_transfer_len = dev->controller.dev->max_bulk_tds * max;
|
||||
}
|
||||
|
||||
for (position = 0, transferred = 0;
|
||||
position < size; position += max_bulk_transfer_len)
|
||||
{
|
||||
current_size = size - position;
|
||||
if (current_size >= max_bulk_transfer_len)
|
||||
current_size = max_bulk_transfer_len;
|
||||
err = VasEBoot_usb_bulk_readwrite (dev, endpoint, current_size,
|
||||
&data[position], type, 1000, &actual);
|
||||
transferred += actual;
|
||||
if (err || (current_size != actual)) break;
|
||||
}
|
||||
|
||||
if (!err && transferred != size)
|
||||
err = VAS_EBOOT_USB_ERR_DATA;
|
||||
return err;
|
||||
}
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_bulk_write (VasEBoot_usb_device_t dev,
|
||||
struct VasEBoot_usb_desc_endp *endpoint,
|
||||
VasEBoot_size_t size, char *data)
|
||||
{
|
||||
return VasEBoot_usb_bulk_readwrite_packetize (dev, endpoint,
|
||||
VAS_EBOOT_USB_TRANSFER_TYPE_OUT,
|
||||
size, data);
|
||||
}
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_bulk_read (VasEBoot_usb_device_t dev,
|
||||
struct VasEBoot_usb_desc_endp *endpoint,
|
||||
VasEBoot_size_t size, char *data)
|
||||
{
|
||||
return VasEBoot_usb_bulk_readwrite_packetize (dev, endpoint,
|
||||
VAS_EBOOT_USB_TRANSFER_TYPE_IN,
|
||||
size, data);
|
||||
}
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_check_transfer (VasEBoot_usb_transfer_t transfer, VasEBoot_size_t *actual)
|
||||
{
|
||||
VasEBoot_usb_err_t err;
|
||||
VasEBoot_usb_device_t dev = transfer->dev;
|
||||
|
||||
err = dev->controller.dev->check_transfer (&dev->controller, transfer,
|
||||
actual);
|
||||
if (err == VAS_EBOOT_USB_ERR_WAIT)
|
||||
return err;
|
||||
|
||||
VasEBoot_usb_bulk_finish_readwrite (transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
VasEBoot_usb_transfer_t
|
||||
VasEBoot_usb_bulk_read_background (VasEBoot_usb_device_t dev,
|
||||
struct VasEBoot_usb_desc_endp *endpoint,
|
||||
VasEBoot_size_t size, void *data)
|
||||
{
|
||||
VasEBoot_usb_err_t err;
|
||||
VasEBoot_usb_transfer_t transfer;
|
||||
|
||||
transfer = VasEBoot_usb_bulk_setup_readwrite (dev, endpoint, size,
|
||||
data, VAS_EBOOT_USB_TRANSFER_TYPE_IN);
|
||||
if (!transfer)
|
||||
return NULL;
|
||||
|
||||
err = dev->controller.dev->setup_transfer (&dev->controller, transfer);
|
||||
if (err)
|
||||
return NULL;
|
||||
|
||||
return transfer;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_usb_cancel_transfer (VasEBoot_usb_transfer_t transfer)
|
||||
{
|
||||
VasEBoot_usb_device_t dev = transfer->dev;
|
||||
dev->controller.dev->cancel_transfer (&dev->controller, transfer);
|
||||
VasEBoot_errno = VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
VasEBoot_usb_err_t
|
||||
VasEBoot_usb_bulk_read_extended (VasEBoot_usb_device_t dev,
|
||||
struct VasEBoot_usb_desc_endp *endpoint,
|
||||
VasEBoot_size_t size, char *data,
|
||||
int timeout, VasEBoot_size_t *actual)
|
||||
{
|
||||
return VasEBoot_usb_bulk_readwrite (dev, endpoint, size, data,
|
||||
VAS_EBOOT_USB_TRANSFER_TYPE_IN, timeout, actual);
|
||||
}
|
||||
|
|
@ -0,0 +1,820 @@
|
|||
/* acpi.c - modify acpi tables. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/file.h>
|
||||
#include <VasEBoot/disk.h>
|
||||
#include <VasEBoot/term.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/acpi.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/memory.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/lockdown.h>
|
||||
|
||||
#ifdef VAS_EBOOT_MACHINE_EFI
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
enum
|
||||
{
|
||||
OPTION_EXCLUDE = 0,
|
||||
OPTION_LOAD_ONLY,
|
||||
OPTION_V1,
|
||||
OPTION_V2,
|
||||
OPTION_OEMID,
|
||||
OPTION_OEMTABLE,
|
||||
OPTION_OEMTABLEREV,
|
||||
OPTION_OEMTABLECREATOR,
|
||||
OPTION_OEMTABLECREATORREV,
|
||||
OPTION_NO_EBDA
|
||||
};
|
||||
|
||||
static const struct VasEBoot_arg_option options[] = {
|
||||
{"exclude", 'x', 0,
|
||||
N_("Don't load host tables specified by comma-separated list."),
|
||||
0, ARG_TYPE_STRING},
|
||||
{"load-only", 'n', 0,
|
||||
N_("Load only tables specified by comma-separated list."), 0, ARG_TYPE_STRING},
|
||||
{"v1", '1', 0, N_("Export version 1 tables to the OS."), 0, ARG_TYPE_NONE},
|
||||
{"v2", '2', 0, N_("Export version 2 and version 3 tables to the OS."), 0, ARG_TYPE_NONE},
|
||||
{"oemid", 'o', 0, N_("Set OEMID of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
|
||||
{"oemtable", 't', 0,
|
||||
N_("Set OEMTABLE ID of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
|
||||
{"oemtablerev", 'r', 0,
|
||||
N_("Set OEMTABLE revision of RSDP, XSDT and RSDT."), 0, ARG_TYPE_INT},
|
||||
{"oemtablecreator", 'c', 0,
|
||||
N_("Set creator field of RSDP, XSDT and RSDT."), 0, ARG_TYPE_STRING},
|
||||
{"oemtablecreatorrev", 'd', 0,
|
||||
N_("Set creator revision of RSDP, XSDT and RSDT."), 0, ARG_TYPE_INT},
|
||||
/* TRANSLATORS: "hangs" here is a noun, not a verb. */
|
||||
{"no-ebda", 'e', 0, N_("Don't update EBDA. May fix failures or hangs on some "
|
||||
"BIOSes but makes it ineffective with OS not receiving RSDP from VAS_EBOOT."),
|
||||
0, ARG_TYPE_NONE},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise.
|
||||
rev2 contains the revision of ACPIv2+ to generate or 0 if none. */
|
||||
static int rev1, rev2;
|
||||
/* OEMID of RSDP, RSDT and XSDT. */
|
||||
static char root_oemid[6];
|
||||
/* OEMTABLE of the same tables. */
|
||||
static char root_oemtable[8];
|
||||
/* OEMREVISION of the same tables. */
|
||||
static VasEBoot_uint32_t root_oemrev;
|
||||
/* CreatorID of the same tables. */
|
||||
static char root_creator_id[4];
|
||||
/* CreatorRevision of the same tables. */
|
||||
static VasEBoot_uint32_t root_creator_rev;
|
||||
static struct VasEBoot_acpi_rsdp_v10 *rsdpv1_new = 0;
|
||||
static struct VasEBoot_acpi_rsdp_v20 *rsdpv2_new = 0;
|
||||
static char *playground = 0, *playground_ptr = 0;
|
||||
static int playground_size = 0;
|
||||
|
||||
/* Linked list of ACPI tables. */
|
||||
struct efiemu_acpi_table
|
||||
{
|
||||
void *addr;
|
||||
VasEBoot_size_t size;
|
||||
struct efiemu_acpi_table *next;
|
||||
};
|
||||
static struct efiemu_acpi_table *acpi_tables = 0;
|
||||
|
||||
/* DSDT isn't in RSDT. So treat it specially. */
|
||||
static void *table_dsdt = 0;
|
||||
/* Pointer to recreated RSDT. */
|
||||
static void *rsdt_addr = 0;
|
||||
|
||||
/* Allocation handles for different tables. */
|
||||
static VasEBoot_size_t dsdt_size = 0;
|
||||
|
||||
/* Address of original FACS. */
|
||||
static VasEBoot_uint32_t facs_addr = 0;
|
||||
|
||||
struct VasEBoot_acpi_rsdp_v20 *
|
||||
VasEBoot_acpi_get_rsdpv2 (void)
|
||||
{
|
||||
if (rsdpv2_new)
|
||||
return rsdpv2_new;
|
||||
if (rsdpv1_new)
|
||||
return 0;
|
||||
return VasEBoot_machine_acpi_get_rsdpv2 ();
|
||||
}
|
||||
|
||||
struct VasEBoot_acpi_rsdp_v10 *
|
||||
VasEBoot_acpi_get_rsdpv1 (void)
|
||||
{
|
||||
if (rsdpv1_new)
|
||||
return rsdpv1_new;
|
||||
if (rsdpv2_new)
|
||||
return 0;
|
||||
return VasEBoot_machine_acpi_get_rsdpv1 ();
|
||||
}
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
|
||||
static inline int
|
||||
iszero (VasEBoot_uint8_t *reg, int size)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
if (reg[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Context for VasEBoot_acpi_create_ebda. */
|
||||
struct VasEBoot_acpi_create_ebda_ctx {
|
||||
int ebda_len;
|
||||
VasEBoot_uint64_t highestlow;
|
||||
};
|
||||
|
||||
/* Helper for VasEBoot_acpi_create_ebda. */
|
||||
static int
|
||||
find_hook (VasEBoot_uint64_t start, VasEBoot_uint64_t size, VasEBoot_memory_type_t type,
|
||||
void *data)
|
||||
{
|
||||
struct VasEBoot_acpi_create_ebda_ctx *ctx = data;
|
||||
VasEBoot_uint64_t end = start + size;
|
||||
if (type != VAS_EBOOT_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
if (end > 0x100000)
|
||||
end = 0x100000;
|
||||
if (end > start + ctx->ebda_len
|
||||
&& ctx->highestlow < ((end - ctx->ebda_len) & (~0xf)) )
|
||||
ctx->highestlow = (end - ctx->ebda_len) & (~0xf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_acpi_create_ebda (void)
|
||||
{
|
||||
struct VasEBoot_acpi_create_ebda_ctx ctx = {
|
||||
.highestlow = 0
|
||||
};
|
||||
int ebda_kb_len = 0;
|
||||
int mmapregion = 0;
|
||||
VasEBoot_uint8_t *ebda, *v1inebda = 0, *v2inebda = 0;
|
||||
VasEBoot_uint8_t *targetebda, *target;
|
||||
struct VasEBoot_acpi_rsdp_v10 *v1;
|
||||
struct VasEBoot_acpi_rsdp_v20 *v2;
|
||||
|
||||
ebda = (VasEBoot_uint8_t *) (VasEBoot_addr_t) ((*((VasEBoot_uint16_t *) VasEBoot_absolute_pointer (0x40e))) << 4);
|
||||
VasEBoot_dprintf ("acpi", "EBDA @%p\n", ebda);
|
||||
if (ebda)
|
||||
ebda_kb_len = *(VasEBoot_uint16_t *) ebda;
|
||||
VasEBoot_dprintf ("acpi", "EBDA length 0x%x\n", ebda_kb_len);
|
||||
if (ebda_kb_len > 16)
|
||||
ebda_kb_len = 0;
|
||||
ctx.ebda_len = (ebda_kb_len + 1) << 10;
|
||||
|
||||
/* FIXME: use low-memory mm allocation once it's available. */
|
||||
VasEBoot_mmap_iterate (find_hook, &ctx);
|
||||
targetebda = (VasEBoot_uint8_t *) (VasEBoot_addr_t) ctx.highestlow;
|
||||
VasEBoot_dprintf ("acpi", "creating ebda @%llx\n",
|
||||
(unsigned long long) ctx.highestlow);
|
||||
if (! ctx.highestlow)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"couldn't find space for the new EBDA");
|
||||
|
||||
mmapregion = VasEBoot_mmap_register ((VasEBoot_addr_t) targetebda, ctx.ebda_len,
|
||||
VAS_EBOOT_MEMORY_RESERVED);
|
||||
if (! mmapregion)
|
||||
return VasEBoot_errno;
|
||||
|
||||
/* XXX: EBDA is unstandardized, so this implementation is heuristical. */
|
||||
if (ebda_kb_len)
|
||||
VasEBoot_memcpy (targetebda, ebda, 0x400);
|
||||
else
|
||||
VasEBoot_memset (targetebda, 0, 0x400);
|
||||
*((VasEBoot_uint16_t *) targetebda) = ebda_kb_len + 1;
|
||||
target = targetebda;
|
||||
|
||||
v1 = VasEBoot_acpi_get_rsdpv1 ();
|
||||
v2 = VasEBoot_acpi_get_rsdpv2 ();
|
||||
if (v2 && v2->length > 40)
|
||||
v2 = 0;
|
||||
|
||||
/* First try to replace already existing rsdp. */
|
||||
if (v2)
|
||||
{
|
||||
VasEBoot_dprintf ("acpi", "Scanning EBDA for old rsdpv2\n");
|
||||
for (; target < targetebda + 0x400 - v2->length; target += 0x10)
|
||||
if (VasEBoot_memcmp (target, VAS_EBOOT_RSDP_SIGNATURE, VAS_EBOOT_RSDP_SIGNATURE_SIZE) == 0
|
||||
&& VasEBoot_byte_checksum (target,
|
||||
sizeof (struct VasEBoot_acpi_rsdp_v10)) == 0
|
||||
&& ((struct VasEBoot_acpi_rsdp_v10 *) target)->revision != 0
|
||||
&& ((struct VasEBoot_acpi_rsdp_v20 *) target)->length <= v2->length)
|
||||
{
|
||||
VasEBoot_memcpy (target, v2, v2->length);
|
||||
VasEBoot_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
|
||||
v2inebda = target;
|
||||
target += v2->length;
|
||||
target = (VasEBoot_uint8_t *) ALIGN_UP((VasEBoot_addr_t) target, 16);
|
||||
v2 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (v1)
|
||||
{
|
||||
VasEBoot_dprintf ("acpi", "Scanning EBDA for old rsdpv1\n");
|
||||
for (; target < targetebda + 0x400 - sizeof (struct VasEBoot_acpi_rsdp_v10);
|
||||
target += 0x10)
|
||||
if (VasEBoot_memcmp (target, VAS_EBOOT_RSDP_SIGNATURE, VAS_EBOOT_RSDP_SIGNATURE_SIZE) == 0
|
||||
&& VasEBoot_byte_checksum (target,
|
||||
sizeof (struct VasEBoot_acpi_rsdp_v10)) == 0)
|
||||
{
|
||||
VasEBoot_memcpy (target, v1, sizeof (struct VasEBoot_acpi_rsdp_v10));
|
||||
VasEBoot_dprintf ("acpi", "Copying rsdpv1 to %p\n", target);
|
||||
v1inebda = target;
|
||||
target += sizeof (struct VasEBoot_acpi_rsdp_v10);
|
||||
target = (VasEBoot_uint8_t *) ALIGN_UP((VasEBoot_addr_t) target, 16);
|
||||
v1 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
target = targetebda + 0x100;
|
||||
|
||||
/* Try contiguous zeros. */
|
||||
if (v2)
|
||||
{
|
||||
VasEBoot_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
|
||||
for (; target < targetebda + 0x400 - v2->length; target += 0x10)
|
||||
if (iszero (target, v2->length))
|
||||
{
|
||||
VasEBoot_dprintf ("acpi", "Copying rsdpv2 to %p\n", target);
|
||||
VasEBoot_memcpy (target, v2, v2->length);
|
||||
v2inebda = target;
|
||||
target += v2->length;
|
||||
target = (VasEBoot_uint8_t *) ALIGN_UP((VasEBoot_addr_t) target, 16);
|
||||
v2 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (v1)
|
||||
{
|
||||
VasEBoot_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
|
||||
for (; target < targetebda + 0x400 - sizeof (struct VasEBoot_acpi_rsdp_v10);
|
||||
target += 0x10)
|
||||
if (iszero (target, sizeof (struct VasEBoot_acpi_rsdp_v10)))
|
||||
{
|
||||
VasEBoot_dprintf ("acpi", "Copying rsdpv1 to %p\n", target);
|
||||
VasEBoot_memcpy (target, v1, sizeof (struct VasEBoot_acpi_rsdp_v10));
|
||||
v1inebda = target;
|
||||
target += sizeof (struct VasEBoot_acpi_rsdp_v10);
|
||||
target = (VasEBoot_uint8_t *) ALIGN_UP((VasEBoot_addr_t) target, 16);
|
||||
v1 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (v1 || v2)
|
||||
{
|
||||
VasEBoot_mmap_unregister (mmapregion);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"couldn't find suitable spot in EBDA");
|
||||
}
|
||||
|
||||
/* Remove any other RSDT. */
|
||||
for (target = targetebda;
|
||||
target < targetebda + 0x400 - sizeof (struct VasEBoot_acpi_rsdp_v10);
|
||||
target += 0x10)
|
||||
if (VasEBoot_memcmp (target, VAS_EBOOT_RSDP_SIGNATURE, VAS_EBOOT_RSDP_SIGNATURE_SIZE) == 0
|
||||
&& VasEBoot_byte_checksum (target,
|
||||
sizeof (struct VasEBoot_acpi_rsdp_v10)) == 0
|
||||
&& target != v1inebda && target != v2inebda)
|
||||
*target = 0;
|
||||
|
||||
VasEBoot_dprintf ("acpi", "Switching EBDA\n");
|
||||
(*((VasEBoot_uint16_t *) VasEBoot_absolute_pointer (0x40e))) = ((VasEBoot_addr_t) targetebda) >> 4;
|
||||
VasEBoot_dprintf ("acpi", "EBDA switched\n");
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create tables common to ACPIv1 and ACPIv2+ */
|
||||
static void
|
||||
setup_common_tables (void)
|
||||
{
|
||||
struct efiemu_acpi_table *cur;
|
||||
struct VasEBoot_acpi_table_header *rsdt;
|
||||
VasEBoot_uint32_t *rsdt_entry;
|
||||
int numoftables;
|
||||
|
||||
/* Treat DSDT. */
|
||||
VasEBoot_memcpy (playground_ptr, table_dsdt, dsdt_size);
|
||||
VasEBoot_free (table_dsdt);
|
||||
table_dsdt = playground_ptr;
|
||||
playground_ptr += dsdt_size;
|
||||
|
||||
/* Treat other tables. */
|
||||
for (cur = acpi_tables; cur; cur = cur->next)
|
||||
{
|
||||
struct VasEBoot_acpi_fadt *fadt;
|
||||
|
||||
VasEBoot_memcpy (playground_ptr, cur->addr, cur->size);
|
||||
VasEBoot_free (cur->addr);
|
||||
cur->addr = playground_ptr;
|
||||
playground_ptr += cur->size;
|
||||
|
||||
/* If it's FADT correct DSDT and FACS addresses. */
|
||||
fadt = (struct VasEBoot_acpi_fadt *) cur->addr;
|
||||
if (VasEBoot_memcmp (fadt->hdr.signature, VAS_EBOOT_ACPI_FADT_SIGNATURE,
|
||||
sizeof (fadt->hdr.signature)) == 0)
|
||||
{
|
||||
fadt->dsdt_addr = (VasEBoot_addr_t) table_dsdt;
|
||||
fadt->facs_addr = facs_addr;
|
||||
|
||||
/* Does a revision 2 exist at all? */
|
||||
if (fadt->hdr.revision >= 3)
|
||||
{
|
||||
fadt->dsdt_xaddr = (VasEBoot_addr_t) table_dsdt;
|
||||
fadt->facs_xaddr = facs_addr;
|
||||
}
|
||||
|
||||
/* Recompute checksum. */
|
||||
fadt->hdr.checksum = 0;
|
||||
fadt->hdr.checksum = 1 + ~VasEBoot_byte_checksum (fadt, fadt->hdr.length);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill RSDT entries. */
|
||||
numoftables = 0;
|
||||
for (cur = acpi_tables; cur; cur = cur->next)
|
||||
numoftables++;
|
||||
|
||||
rsdt_addr = rsdt = (struct VasEBoot_acpi_table_header *) playground_ptr;
|
||||
playground_ptr += sizeof (struct VasEBoot_acpi_table_header) + sizeof (VasEBoot_uint32_t) * numoftables;
|
||||
|
||||
rsdt_entry = (VasEBoot_uint32_t *) (rsdt + 1);
|
||||
|
||||
/* Fill RSDT header. */
|
||||
VasEBoot_memcpy (&(rsdt->signature), "RSDT", 4);
|
||||
rsdt->length = sizeof (struct VasEBoot_acpi_table_header) + sizeof (VasEBoot_uint32_t) * numoftables;
|
||||
rsdt->revision = 1;
|
||||
VasEBoot_memcpy (&(rsdt->oemid), root_oemid, sizeof (rsdt->oemid));
|
||||
VasEBoot_memcpy (&(rsdt->oemtable), root_oemtable, sizeof (rsdt->oemtable));
|
||||
rsdt->oemrev = root_oemrev;
|
||||
VasEBoot_memcpy (&(rsdt->creator_id), root_creator_id, sizeof (rsdt->creator_id));
|
||||
rsdt->creator_rev = root_creator_rev;
|
||||
|
||||
for (cur = acpi_tables; cur; cur = cur->next)
|
||||
*(rsdt_entry++) = (VasEBoot_addr_t) cur->addr;
|
||||
|
||||
/* Recompute checksum. */
|
||||
rsdt->checksum = 0;
|
||||
rsdt->checksum = 1 + ~VasEBoot_byte_checksum (rsdt, rsdt->length);
|
||||
}
|
||||
|
||||
/* Regenerate ACPIv1 RSDP */
|
||||
static void
|
||||
setv1table (void)
|
||||
{
|
||||
/* Create RSDP. */
|
||||
rsdpv1_new = (struct VasEBoot_acpi_rsdp_v10 *) playground_ptr;
|
||||
playground_ptr += sizeof (struct VasEBoot_acpi_rsdp_v10);
|
||||
VasEBoot_memcpy (&(rsdpv1_new->signature), VAS_EBOOT_RSDP_SIGNATURE,
|
||||
sizeof (rsdpv1_new->signature));
|
||||
VasEBoot_memcpy (&(rsdpv1_new->oemid), root_oemid, sizeof (rsdpv1_new->oemid));
|
||||
rsdpv1_new->revision = 0;
|
||||
rsdpv1_new->rsdt_addr = (VasEBoot_addr_t) rsdt_addr;
|
||||
rsdpv1_new->checksum = 0;
|
||||
rsdpv1_new->checksum = 1 + ~VasEBoot_byte_checksum (rsdpv1_new,
|
||||
sizeof (*rsdpv1_new));
|
||||
VasEBoot_dprintf ("acpi", "Generated ACPIv1 tables\n");
|
||||
}
|
||||
|
||||
static void
|
||||
setv2table (void)
|
||||
{
|
||||
struct VasEBoot_acpi_table_header *xsdt;
|
||||
struct efiemu_acpi_table *cur;
|
||||
VasEBoot_uint64_t *xsdt_entry;
|
||||
int numoftables;
|
||||
|
||||
numoftables = 0;
|
||||
for (cur = acpi_tables; cur; cur = cur->next)
|
||||
numoftables++;
|
||||
|
||||
/* Create XSDT. */
|
||||
xsdt = (struct VasEBoot_acpi_table_header *) playground_ptr;
|
||||
playground_ptr += sizeof (struct VasEBoot_acpi_table_header) + sizeof (VasEBoot_uint64_t) * numoftables;
|
||||
|
||||
xsdt_entry = (VasEBoot_uint64_t *)(xsdt + 1);
|
||||
for (cur = acpi_tables; cur; cur = cur->next)
|
||||
*(xsdt_entry++) = (VasEBoot_addr_t) cur->addr;
|
||||
VasEBoot_memcpy (&(xsdt->signature), "XSDT", 4);
|
||||
xsdt->length = sizeof (struct VasEBoot_acpi_table_header) + sizeof (VasEBoot_uint64_t) * numoftables;
|
||||
xsdt->revision = 1;
|
||||
VasEBoot_memcpy (&(xsdt->oemid), root_oemid, sizeof (xsdt->oemid));
|
||||
VasEBoot_memcpy (&(xsdt->oemtable), root_oemtable, sizeof (xsdt->oemtable));
|
||||
xsdt->oemrev = root_oemrev;
|
||||
VasEBoot_memcpy (&(xsdt->creator_id), root_creator_id, sizeof (xsdt->creator_id));
|
||||
xsdt->creator_rev = root_creator_rev;
|
||||
xsdt->checksum = 0;
|
||||
xsdt->checksum = 1 + ~VasEBoot_byte_checksum (xsdt, xsdt->length);
|
||||
|
||||
/* Create RSDPv2. */
|
||||
rsdpv2_new = (struct VasEBoot_acpi_rsdp_v20 *) playground_ptr;
|
||||
playground_ptr += sizeof (struct VasEBoot_acpi_rsdp_v20);
|
||||
VasEBoot_memcpy (&(rsdpv2_new->rsdpv1.signature), VAS_EBOOT_RSDP_SIGNATURE,
|
||||
sizeof (rsdpv2_new->rsdpv1.signature));
|
||||
VasEBoot_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid,
|
||||
sizeof (rsdpv2_new->rsdpv1.oemid));
|
||||
rsdpv2_new->rsdpv1.revision = rev2;
|
||||
rsdpv2_new->rsdpv1.rsdt_addr = (VasEBoot_addr_t) rsdt_addr;
|
||||
rsdpv2_new->rsdpv1.checksum = 0;
|
||||
rsdpv2_new->rsdpv1.checksum = 1 + ~VasEBoot_byte_checksum
|
||||
(&(rsdpv2_new->rsdpv1), sizeof (rsdpv2_new->rsdpv1));
|
||||
rsdpv2_new->length = sizeof (*rsdpv2_new);
|
||||
rsdpv2_new->xsdt_addr = (VasEBoot_addr_t) xsdt;
|
||||
rsdpv2_new->checksum = 0;
|
||||
rsdpv2_new->checksum = 1 + ~VasEBoot_byte_checksum (rsdpv2_new,
|
||||
rsdpv2_new->length);
|
||||
VasEBoot_dprintf ("acpi", "Generated ACPIv2 tables\n");
|
||||
}
|
||||
|
||||
static void
|
||||
free_tables (void)
|
||||
{
|
||||
struct efiemu_acpi_table *cur, *t;
|
||||
if (table_dsdt)
|
||||
VasEBoot_free (table_dsdt);
|
||||
for (cur = acpi_tables; cur;)
|
||||
{
|
||||
t = cur;
|
||||
VasEBoot_free (cur->addr);
|
||||
cur = cur->next;
|
||||
VasEBoot_free (t);
|
||||
}
|
||||
acpi_tables = 0;
|
||||
table_dsdt = 0;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_acpi (struct VasEBoot_extcmd_context *ctxt, int argc, char **args)
|
||||
{
|
||||
struct VasEBoot_arg_list *state = ctxt->state;
|
||||
struct VasEBoot_acpi_rsdp_v10 *rsdp;
|
||||
struct efiemu_acpi_table *cur, *t;
|
||||
int i, mmapregion;
|
||||
int numoftables;
|
||||
|
||||
/* Default values if no RSDP is found. */
|
||||
rev1 = 1;
|
||||
rev2 = 3;
|
||||
|
||||
facs_addr = 0;
|
||||
playground = playground_ptr = 0;
|
||||
playground_size = 0;
|
||||
|
||||
rsdp = (struct VasEBoot_acpi_rsdp_v10 *) VasEBoot_machine_acpi_get_rsdpv2 ();
|
||||
|
||||
if (! rsdp)
|
||||
rsdp = VasEBoot_machine_acpi_get_rsdpv1 ();
|
||||
|
||||
VasEBoot_dprintf ("acpi", "RSDP @%p\n", rsdp);
|
||||
|
||||
if (rsdp)
|
||||
{
|
||||
VasEBoot_uint8_t *entry_ptr;
|
||||
char *exclude = 0;
|
||||
char *load_only = 0;
|
||||
char *ptr;
|
||||
VasEBoot_size_t tbl_addr_size;
|
||||
struct VasEBoot_acpi_table_header *table_head;
|
||||
|
||||
exclude = state[OPTION_EXCLUDE].set ? VasEBoot_strdup (state[OPTION_EXCLUDE].arg) : 0;
|
||||
if (exclude)
|
||||
{
|
||||
for (ptr = exclude; *ptr; ptr++)
|
||||
*ptr = VasEBoot_tolower (*ptr);
|
||||
}
|
||||
|
||||
load_only = state[OPTION_LOAD_ONLY].set ? VasEBoot_strdup (state[OPTION_LOAD_ONLY].arg) : 0;
|
||||
if (load_only)
|
||||
{
|
||||
for (ptr = load_only; *ptr; ptr++)
|
||||
*ptr = VasEBoot_tolower (*ptr);
|
||||
}
|
||||
|
||||
/* Set revision variables to replicate the same version as host. */
|
||||
rev1 = ! rsdp->revision;
|
||||
rev2 = rsdp->revision;
|
||||
if (rev2 && ((struct VasEBoot_acpi_table_header *) (VasEBoot_addr_t) ((struct VasEBoot_acpi_rsdp_v20 *) rsdp)->xsdt_addr) != NULL)
|
||||
{
|
||||
/* XSDT consists of header and an array of 64-bit pointers. */
|
||||
table_head = (struct VasEBoot_acpi_table_header *) (VasEBoot_addr_t) ((struct VasEBoot_acpi_rsdp_v20 *) rsdp)->xsdt_addr;
|
||||
tbl_addr_size = sizeof (((struct VasEBoot_acpi_rsdp_v20 *) rsdp)->xsdt_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RSDT consists of header and an array of 32-bit pointers. */
|
||||
table_head = (struct VasEBoot_acpi_table_header *) (VasEBoot_addr_t) rsdp->rsdt_addr;
|
||||
tbl_addr_size = sizeof (rsdp->rsdt_addr);
|
||||
}
|
||||
|
||||
/* Load host tables. */
|
||||
for (entry_ptr = (VasEBoot_uint8_t *) (table_head + 1);
|
||||
entry_ptr < (VasEBoot_uint8_t *) (((VasEBoot_uint8_t *) table_head) + table_head->length);
|
||||
entry_ptr += tbl_addr_size)
|
||||
{
|
||||
char signature[5];
|
||||
struct efiemu_acpi_table *table;
|
||||
struct VasEBoot_acpi_table_header *curtable;
|
||||
if (tbl_addr_size == sizeof (rsdp->rsdt_addr))
|
||||
curtable = (struct VasEBoot_acpi_table_header *) (VasEBoot_addr_t) *((VasEBoot_uint32_t *) entry_ptr);
|
||||
else
|
||||
curtable = (struct VasEBoot_acpi_table_header *) (VasEBoot_addr_t) *((VasEBoot_uint64_t *) entry_ptr);
|
||||
|
||||
signature[4] = 0;
|
||||
for (i = 0; i < 4;i++)
|
||||
signature[i] = VasEBoot_tolower (curtable->signature[i]);
|
||||
|
||||
/* If it's FADT it contains addresses of DSDT and FACS. */
|
||||
if (VasEBoot_strcmp (signature, "facp") == 0)
|
||||
{
|
||||
struct VasEBoot_acpi_table_header *dsdt;
|
||||
struct VasEBoot_acpi_fadt *fadt = (struct VasEBoot_acpi_fadt *) curtable;
|
||||
|
||||
/* Set root header variables to the same values
|
||||
as FADT by default. */
|
||||
VasEBoot_memcpy (&root_oemid, &(fadt->hdr.oemid),
|
||||
sizeof (root_oemid));
|
||||
VasEBoot_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
|
||||
sizeof (root_oemtable));
|
||||
root_oemrev = fadt->hdr.oemrev;
|
||||
VasEBoot_memcpy (&root_creator_id, &(fadt->hdr.creator_id),
|
||||
sizeof (root_creator_id));
|
||||
root_creator_rev = fadt->hdr.creator_rev;
|
||||
|
||||
/* Load DSDT if not excluded. */
|
||||
dsdt = (struct VasEBoot_acpi_table_header *)
|
||||
(VasEBoot_addr_t) fadt->dsdt_addr;
|
||||
if (dsdt && (! exclude || ! VasEBoot_strword (exclude, "dsdt"))
|
||||
&& (! load_only || VasEBoot_strword (load_only, "dsdt"))
|
||||
&& dsdt->length >= sizeof (*dsdt))
|
||||
{
|
||||
dsdt_size = dsdt->length;
|
||||
table_dsdt = VasEBoot_malloc (dsdt->length);
|
||||
if (! table_dsdt)
|
||||
{
|
||||
free_tables ();
|
||||
VasEBoot_free (exclude);
|
||||
VasEBoot_free (load_only);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
VasEBoot_memcpy (table_dsdt, dsdt, dsdt->length);
|
||||
}
|
||||
|
||||
/* Save FACS address. FACS shouldn't be overridden. */
|
||||
facs_addr = fadt->facs_addr;
|
||||
}
|
||||
|
||||
/* Skip excluded tables. */
|
||||
if (exclude && VasEBoot_strword (exclude, signature))
|
||||
continue;
|
||||
if (load_only && ! VasEBoot_strword (load_only, signature))
|
||||
continue;
|
||||
|
||||
/* Sanity check. */
|
||||
if (curtable->length < sizeof (*curtable))
|
||||
continue;
|
||||
|
||||
table = (struct efiemu_acpi_table *) VasEBoot_malloc
|
||||
(sizeof (struct efiemu_acpi_table));
|
||||
if (! table)
|
||||
{
|
||||
free_tables ();
|
||||
VasEBoot_free (exclude);
|
||||
VasEBoot_free (load_only);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
table->size = curtable->length;
|
||||
table->addr = VasEBoot_malloc (table->size);
|
||||
playground_size += table->size;
|
||||
if (! table->addr)
|
||||
{
|
||||
free_tables ();
|
||||
VasEBoot_free (exclude);
|
||||
VasEBoot_free (load_only);
|
||||
VasEBoot_free (table);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
table->next = acpi_tables;
|
||||
acpi_tables = table;
|
||||
VasEBoot_memcpy (table->addr, curtable, table->size);
|
||||
}
|
||||
VasEBoot_free (exclude);
|
||||
VasEBoot_free (load_only);
|
||||
}
|
||||
|
||||
/* Does user specify versions to generate? */
|
||||
if (state[OPTION_V1].set || state[OPTION_V2].set)
|
||||
{
|
||||
rev1 = state[OPTION_V1].set;
|
||||
if (state[OPTION_V2].set)
|
||||
rev2 = rev2 ? : 2;
|
||||
else
|
||||
rev2 = 0;
|
||||
}
|
||||
|
||||
/* Does user override root header information? */
|
||||
if (state[OPTION_OEMID].set)
|
||||
VasEBoot_strncpy (root_oemid, state[OPTION_OEMID].arg, sizeof (root_oemid));
|
||||
if (state[OPTION_OEMTABLE].set)
|
||||
VasEBoot_strncpy (root_oemtable, state[OPTION_OEMTABLE].arg, sizeof (root_oemtable));
|
||||
if (state[OPTION_OEMTABLEREV].set)
|
||||
root_oemrev = VasEBoot_strtoul (state[OPTION_OEMTABLEREV].arg, 0, 0);
|
||||
if (state[OPTION_OEMTABLECREATOR].set)
|
||||
VasEBoot_strncpy (root_creator_id, state[OPTION_OEMTABLECREATOR].arg, sizeof (root_creator_id));
|
||||
if (state[OPTION_OEMTABLECREATORREV].set)
|
||||
root_creator_rev = VasEBoot_strtoul (state[OPTION_OEMTABLECREATORREV].arg, 0, 0);
|
||||
|
||||
/* Load user tables */
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
VasEBoot_file_t file;
|
||||
VasEBoot_size_t size;
|
||||
char *buf;
|
||||
|
||||
file = VasEBoot_file_open (args[i], VAS_EBOOT_FILE_TYPE_ACPI_TABLE);
|
||||
if (! file)
|
||||
{
|
||||
free_tables ();
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
size = VasEBoot_file_size (file);
|
||||
if (size < sizeof (struct VasEBoot_acpi_table_header))
|
||||
{
|
||||
VasEBoot_file_close (file);
|
||||
free_tables ();
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
args[i]);
|
||||
}
|
||||
|
||||
buf = (char *) VasEBoot_malloc (size);
|
||||
if (! buf)
|
||||
{
|
||||
VasEBoot_file_close (file);
|
||||
free_tables ();
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
if (VasEBoot_file_read (file, buf, size) != (int) size)
|
||||
{
|
||||
VasEBoot_file_close (file);
|
||||
free_tables ();
|
||||
if (!VasEBoot_errno)
|
||||
VasEBoot_error (VAS_EBOOT_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
args[i]);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
VasEBoot_file_close (file);
|
||||
|
||||
if (VasEBoot_memcmp (((struct VasEBoot_acpi_table_header *) buf)->signature,
|
||||
"DSDT", 4) == 0)
|
||||
{
|
||||
VasEBoot_free (table_dsdt);
|
||||
table_dsdt = buf;
|
||||
dsdt_size = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct efiemu_acpi_table *table;
|
||||
table = (struct efiemu_acpi_table *) VasEBoot_malloc
|
||||
(sizeof (struct efiemu_acpi_table));
|
||||
if (! table)
|
||||
{
|
||||
free_tables ();
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
table->size = size;
|
||||
table->addr = buf;
|
||||
playground_size += table->size;
|
||||
|
||||
table->next = acpi_tables;
|
||||
acpi_tables = table;
|
||||
}
|
||||
}
|
||||
|
||||
numoftables = 0;
|
||||
for (cur = acpi_tables; cur; cur = cur->next)
|
||||
numoftables++;
|
||||
|
||||
/* DSDT. */
|
||||
playground_size += dsdt_size;
|
||||
/* RSDT. */
|
||||
playground_size += sizeof (struct VasEBoot_acpi_table_header) + sizeof (VasEBoot_uint32_t) * numoftables;
|
||||
/* RSDPv1. */
|
||||
playground_size += sizeof (struct VasEBoot_acpi_rsdp_v10);
|
||||
/* XSDT. */
|
||||
playground_size += sizeof (struct VasEBoot_acpi_table_header) + sizeof (VasEBoot_uint64_t) * numoftables;
|
||||
/* RSDPv2. */
|
||||
playground_size += sizeof (struct VasEBoot_acpi_rsdp_v20);
|
||||
|
||||
playground = playground_ptr
|
||||
= VasEBoot_mmap_malign_and_register (1, playground_size, &mmapregion,
|
||||
VAS_EBOOT_MEMORY_ACPI, 0);
|
||||
|
||||
if (! playground)
|
||||
{
|
||||
free_tables ();
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"couldn't allocate space for ACPI tables");
|
||||
}
|
||||
|
||||
setup_common_tables ();
|
||||
|
||||
/* Request space for RSDPv1. */
|
||||
if (rev1)
|
||||
setv1table ();
|
||||
|
||||
/* Request space for RSDPv2+ and XSDT. */
|
||||
if (rev2)
|
||||
setv2table ();
|
||||
|
||||
for (cur = acpi_tables; cur;)
|
||||
{
|
||||
t = cur;
|
||||
cur = cur->next;
|
||||
VasEBoot_free (t);
|
||||
}
|
||||
acpi_tables = 0;
|
||||
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
if (! state[OPTION_NO_EBDA].set)
|
||||
{
|
||||
VasEBoot_err_t err;
|
||||
err = VasEBoot_acpi_create_ebda ();
|
||||
if (err)
|
||||
{
|
||||
rsdpv1_new = 0;
|
||||
rsdpv2_new = 0;
|
||||
VasEBoot_mmap_free_and_unregister (mmapregion);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VAS_EBOOT_MACHINE_EFI
|
||||
{
|
||||
static VasEBoot_guid_t acpi = VAS_EBOOT_EFI_ACPI_TABLE_GUID;
|
||||
static VasEBoot_guid_t acpi20 = VAS_EBOOT_EFI_ACPI_20_TABLE_GUID;
|
||||
|
||||
VasEBoot_efi_system_table->boot_services->install_configuration_table (&acpi20,
|
||||
VasEBoot_acpi_get_rsdpv2 ());
|
||||
VasEBoot_efi_system_table->boot_services->install_configuration_table (&acpi,
|
||||
VasEBoot_acpi_get_rsdpv1 ());
|
||||
}
|
||||
#endif
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(acpi)
|
||||
{
|
||||
cmd = VasEBoot_register_extcmd_lockdown ("acpi", VasEBoot_cmd_acpi, 0,
|
||||
N_("[-1|-2] [--exclude=TABLE1,TABLE2|"
|
||||
"--load-only=TABLE1,TABLE2] FILE1"
|
||||
" [FILE2] [...]"),
|
||||
N_("Load host ACPI tables and tables "
|
||||
"specified by arguments."),
|
||||
options);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(acpi)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef VAS_EBOOT_DSDT_TEST
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define VasEBoot_dprintf(cond, args...) printf ( args )
|
||||
#define VasEBoot_printf printf
|
||||
#define VasEBoot_util_fopen fopen
|
||||
#define VasEBoot_memcmp memcmp
|
||||
typedef uint64_t VasEBoot_uint64_t;
|
||||
typedef uint32_t VasEBoot_uint32_t;
|
||||
typedef uint16_t VasEBoot_uint16_t;
|
||||
typedef uint8_t VasEBoot_uint8_t;
|
||||
|
||||
#endif
|
||||
|
||||
#include <VasEBoot/acpi.h>
|
||||
#ifndef VAS_EBOOT_DSDT_TEST
|
||||
#include <VasEBoot/i18n.h>
|
||||
#else
|
||||
#define _(x) x
|
||||
#define N_(x) x
|
||||
#endif
|
||||
|
||||
#ifndef VAS_EBOOT_DSDT_TEST
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/time.h>
|
||||
#include <VasEBoot/cpu/io.h>
|
||||
#endif
|
||||
|
||||
static inline VasEBoot_uint32_t
|
||||
decode_length (const VasEBoot_uint8_t *ptr, int *numlen)
|
||||
{
|
||||
int num_bytes, i;
|
||||
VasEBoot_uint32_t ret;
|
||||
if (*ptr < 64)
|
||||
{
|
||||
if (numlen)
|
||||
*numlen = 1;
|
||||
return *ptr;
|
||||
}
|
||||
num_bytes = *ptr >> 6;
|
||||
if (numlen)
|
||||
*numlen = num_bytes + 1;
|
||||
ret = *ptr & 0xf;
|
||||
ptr++;
|
||||
for (i = 0; i < num_bytes; i++)
|
||||
{
|
||||
ret |= *ptr << (8 * i + 4);
|
||||
ptr++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline VasEBoot_uint32_t
|
||||
skip_name_string (const VasEBoot_uint8_t *ptr, const VasEBoot_uint8_t *end)
|
||||
{
|
||||
const VasEBoot_uint8_t *ptr0 = ptr;
|
||||
|
||||
while (ptr < end && (*ptr == '^' || *ptr == '\\'))
|
||||
ptr++;
|
||||
switch (*ptr)
|
||||
{
|
||||
case '.':
|
||||
ptr++;
|
||||
ptr += 8;
|
||||
break;
|
||||
case '/':
|
||||
ptr++;
|
||||
ptr += 1 + (*ptr) * 4;
|
||||
break;
|
||||
case 0:
|
||||
ptr++;
|
||||
break;
|
||||
default:
|
||||
ptr += 4;
|
||||
break;
|
||||
}
|
||||
return ptr - ptr0;
|
||||
}
|
||||
|
||||
static inline VasEBoot_uint32_t
|
||||
skip_data_ref_object (const VasEBoot_uint8_t *ptr, const VasEBoot_uint8_t *end)
|
||||
{
|
||||
VasEBoot_dprintf ("acpi", "data type = 0x%x\n", *ptr);
|
||||
switch (*ptr)
|
||||
{
|
||||
case VAS_EBOOT_ACPI_OPCODE_PACKAGE:
|
||||
case VAS_EBOOT_ACPI_OPCODE_BUFFER:
|
||||
return 1 + decode_length (ptr + 1, 0);
|
||||
case VAS_EBOOT_ACPI_OPCODE_ZERO:
|
||||
case VAS_EBOOT_ACPI_OPCODE_ONES:
|
||||
case VAS_EBOOT_ACPI_OPCODE_ONE:
|
||||
return 1;
|
||||
case VAS_EBOOT_ACPI_OPCODE_BYTE_CONST:
|
||||
return 2;
|
||||
case VAS_EBOOT_ACPI_OPCODE_WORD_CONST:
|
||||
return 3;
|
||||
case VAS_EBOOT_ACPI_OPCODE_DWORD_CONST:
|
||||
return 5;
|
||||
case VAS_EBOOT_ACPI_OPCODE_STRING_CONST:
|
||||
{
|
||||
const VasEBoot_uint8_t *ptr0 = ptr;
|
||||
for (ptr++; ptr < end && *ptr; ptr++);
|
||||
if (ptr == end)
|
||||
return 0;
|
||||
return ptr - ptr0 + 1;
|
||||
}
|
||||
default:
|
||||
if (*ptr == '^' || *ptr == '\\' || *ptr == '_'
|
||||
|| (*ptr >= 'A' && *ptr <= 'Z'))
|
||||
return skip_name_string (ptr, end);
|
||||
VasEBoot_printf ("Unknown opcode 0x%x\n", *ptr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline VasEBoot_uint32_t
|
||||
skip_term (const VasEBoot_uint8_t *ptr, const VasEBoot_uint8_t *end)
|
||||
{
|
||||
VasEBoot_uint32_t add;
|
||||
const VasEBoot_uint8_t *ptr0 = ptr;
|
||||
|
||||
switch(*ptr)
|
||||
{
|
||||
case VAS_EBOOT_ACPI_OPCODE_ADD:
|
||||
case VAS_EBOOT_ACPI_OPCODE_AND:
|
||||
case VAS_EBOOT_ACPI_OPCODE_CONCAT:
|
||||
case VAS_EBOOT_ACPI_OPCODE_CONCATRES:
|
||||
case VAS_EBOOT_ACPI_OPCODE_DIVIDE:
|
||||
case VAS_EBOOT_ACPI_OPCODE_INDEX:
|
||||
case VAS_EBOOT_ACPI_OPCODE_LSHIFT:
|
||||
case VAS_EBOOT_ACPI_OPCODE_MOD:
|
||||
case VAS_EBOOT_ACPI_OPCODE_MULTIPLY:
|
||||
case VAS_EBOOT_ACPI_OPCODE_NAND:
|
||||
case VAS_EBOOT_ACPI_OPCODE_NOR:
|
||||
case VAS_EBOOT_ACPI_OPCODE_OR:
|
||||
case VAS_EBOOT_ACPI_OPCODE_RSHIFT:
|
||||
case VAS_EBOOT_ACPI_OPCODE_SUBTRACT:
|
||||
case VAS_EBOOT_ACPI_OPCODE_TOSTRING:
|
||||
case VAS_EBOOT_ACPI_OPCODE_XOR:
|
||||
/*
|
||||
* Parameters for these opcodes: TermArg, TermArg Target, see ACPI
|
||||
* spec r5.0, page 828f.
|
||||
*/
|
||||
ptr++;
|
||||
ptr += add = skip_term (ptr, end);
|
||||
if (!add)
|
||||
return 0;
|
||||
ptr += add = skip_term (ptr, end);
|
||||
if (!add)
|
||||
return 0;
|
||||
ptr += skip_name_string (ptr, end);
|
||||
break;
|
||||
default:
|
||||
return skip_data_ref_object (ptr, end);
|
||||
}
|
||||
return ptr - ptr0;
|
||||
}
|
||||
|
||||
static inline VasEBoot_uint32_t
|
||||
skip_ext_op (const VasEBoot_uint8_t *ptr, const VasEBoot_uint8_t *end)
|
||||
{
|
||||
const VasEBoot_uint8_t *ptr0 = ptr;
|
||||
int add;
|
||||
VasEBoot_dprintf ("acpi", "Extended opcode: 0x%x\n", *ptr);
|
||||
switch (*ptr)
|
||||
{
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_MUTEX:
|
||||
ptr++;
|
||||
ptr += skip_name_string (ptr, end);
|
||||
ptr++;
|
||||
break;
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_EVENT_OP:
|
||||
ptr++;
|
||||
ptr += skip_name_string (ptr, end);
|
||||
break;
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_OPERATION_REGION:
|
||||
ptr++;
|
||||
ptr += skip_name_string (ptr, end);
|
||||
ptr++;
|
||||
ptr += add = skip_term (ptr, end);
|
||||
if (!add)
|
||||
return 0;
|
||||
ptr += add = skip_term (ptr, end);
|
||||
if (!add)
|
||||
return 0;
|
||||
break;
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_FIELD_OP:
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_DEVICE_OP:
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_PROCESSOR_OP:
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_POWER_RES_OP:
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_THERMAL_ZONE_OP:
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_INDEX_FIELD_OP:
|
||||
case VAS_EBOOT_ACPI_EXTOPCODE_BANK_FIELD_OP:
|
||||
ptr++;
|
||||
ptr += decode_length (ptr, 0);
|
||||
break;
|
||||
default:
|
||||
VasEBoot_printf ("Unexpected extended opcode: 0x%x\n", *ptr);
|
||||
return 0;
|
||||
}
|
||||
return ptr - ptr0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_sleep_type (VasEBoot_uint8_t *table, VasEBoot_uint8_t *ptr, VasEBoot_uint8_t *end,
|
||||
VasEBoot_uint8_t *scope, int scope_len)
|
||||
{
|
||||
VasEBoot_uint8_t *prev = table;
|
||||
|
||||
if (!ptr)
|
||||
ptr = table + sizeof (struct VasEBoot_acpi_table_header);
|
||||
while (ptr < end && prev < ptr)
|
||||
{
|
||||
int add;
|
||||
prev = ptr;
|
||||
VasEBoot_dprintf ("acpi", "Opcode 0x%x\n", *ptr);
|
||||
VasEBoot_dprintf ("acpi", "Tell %x\n", (unsigned) (ptr - table));
|
||||
switch (*ptr)
|
||||
{
|
||||
case VAS_EBOOT_ACPI_OPCODE_EXTOP:
|
||||
ptr++;
|
||||
ptr += add = skip_ext_op (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
break;
|
||||
case VAS_EBOOT_ACPI_OPCODE_CREATE_DWORD_FIELD:
|
||||
case VAS_EBOOT_ACPI_OPCODE_CREATE_WORD_FIELD:
|
||||
case VAS_EBOOT_ACPI_OPCODE_CREATE_BYTE_FIELD:
|
||||
{
|
||||
ptr += 5;
|
||||
ptr += add = skip_data_ref_object (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
ptr += 4;
|
||||
break;
|
||||
}
|
||||
case VAS_EBOOT_ACPI_OPCODE_NAME:
|
||||
ptr++;
|
||||
if ((!scope || VasEBoot_memcmp (scope, "\\", scope_len) == 0) &&
|
||||
(VasEBoot_memcmp (ptr, "_S5_", 4) == 0 || VasEBoot_memcmp (ptr, "\\_S5_", 4) == 0))
|
||||
{
|
||||
int ll;
|
||||
VasEBoot_uint8_t *ptr2 = ptr;
|
||||
VasEBoot_dprintf ("acpi", "S5 found\n");
|
||||
ptr2 += skip_name_string (ptr, end);
|
||||
if (*ptr2 != 0x12)
|
||||
{
|
||||
VasEBoot_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2);
|
||||
return -1;
|
||||
}
|
||||
ptr2++;
|
||||
decode_length (ptr2, &ll);
|
||||
ptr2 += ll;
|
||||
ptr2++;
|
||||
switch (*ptr2)
|
||||
{
|
||||
case VAS_EBOOT_ACPI_OPCODE_ZERO:
|
||||
return 0;
|
||||
case VAS_EBOOT_ACPI_OPCODE_ONE:
|
||||
return 1;
|
||||
case VAS_EBOOT_ACPI_OPCODE_BYTE_CONST:
|
||||
return ptr2[1];
|
||||
default:
|
||||
VasEBoot_printf ("Unknown data type in _S5: 0x%x\n", *ptr2);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ptr += add = skip_name_string (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
ptr += add = skip_data_ref_object (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
break;
|
||||
case VAS_EBOOT_ACPI_OPCODE_ALIAS:
|
||||
ptr++;
|
||||
/* We need to skip two name strings */
|
||||
ptr += add = skip_name_string (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
ptr += add = skip_name_string (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case VAS_EBOOT_ACPI_OPCODE_SCOPE:
|
||||
{
|
||||
int scope_sleep_type;
|
||||
int ll;
|
||||
VasEBoot_uint8_t *name;
|
||||
int name_len;
|
||||
|
||||
ptr++;
|
||||
add = decode_length (ptr, &ll);
|
||||
name = ptr + ll;
|
||||
name_len = skip_name_string (name, ptr + add);
|
||||
if (!name_len)
|
||||
return -1;
|
||||
scope_sleep_type = get_sleep_type (table, name + name_len,
|
||||
ptr + add, name, name_len);
|
||||
if (scope_sleep_type != -2)
|
||||
return scope_sleep_type;
|
||||
ptr += add;
|
||||
break;
|
||||
}
|
||||
case VAS_EBOOT_ACPI_OPCODE_IF:
|
||||
case VAS_EBOOT_ACPI_OPCODE_METHOD:
|
||||
{
|
||||
ptr++;
|
||||
ptr += decode_length (ptr, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
VasEBoot_printf ("Unknown opcode 0x%x\n", *ptr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
#ifdef VAS_EBOOT_DSDT_TEST
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
FILE *f;
|
||||
size_t len;
|
||||
unsigned char *buf;
|
||||
if (argc < 2)
|
||||
printf ("Usage: %s FILE\n", argv[0]);
|
||||
f = VasEBoot_util_fopen (argv[1], "rb");
|
||||
if (!f)
|
||||
{
|
||||
printf ("Couldn't open file\n");
|
||||
return 1;
|
||||
}
|
||||
fseek (f, 0, SEEK_END);
|
||||
len = ftell (f);
|
||||
fseek (f, 0, SEEK_SET);
|
||||
buf = malloc (len);
|
||||
if (!buf)
|
||||
{
|
||||
printf (_("error: %s.\n"), _("out of memory"));
|
||||
fclose (f);
|
||||
return 2;
|
||||
}
|
||||
if (fread (buf, 1, len, f) != len)
|
||||
{
|
||||
printf (_("cannot read `%s': %s"), argv[1], strerror (errno));
|
||||
free (buf);
|
||||
fclose (f);
|
||||
return 2;
|
||||
}
|
||||
|
||||
printf ("Sleep type = %d\n", get_sleep_type (buf, NULL, buf + len, NULL, 0));
|
||||
free (buf);
|
||||
fclose (f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
VasEBoot_acpi_halt (void)
|
||||
{
|
||||
struct VasEBoot_acpi_rsdp_v20 *rsdp2;
|
||||
struct VasEBoot_acpi_rsdp_v10 *rsdp1;
|
||||
struct VasEBoot_acpi_table_header *rsdt;
|
||||
VasEBoot_uint32_t *entry_ptr;
|
||||
VasEBoot_uint32_t port = 0;
|
||||
int sleep_type = -1;
|
||||
|
||||
rsdp2 = VasEBoot_acpi_get_rsdpv2 ();
|
||||
if (rsdp2)
|
||||
rsdp1 = &(rsdp2->rsdpv1);
|
||||
else
|
||||
rsdp1 = VasEBoot_acpi_get_rsdpv1 ();
|
||||
VasEBoot_dprintf ("acpi", "rsdp1=%p\n", rsdp1);
|
||||
if (!rsdp1)
|
||||
return;
|
||||
|
||||
rsdt = (struct VasEBoot_acpi_table_header *) (VasEBoot_addr_t) rsdp1->rsdt_addr;
|
||||
for (entry_ptr = (VasEBoot_uint32_t *) (rsdt + 1);
|
||||
entry_ptr < (VasEBoot_uint32_t *) (((VasEBoot_uint8_t *) rsdt)
|
||||
+ rsdt->length);
|
||||
entry_ptr++)
|
||||
{
|
||||
if (VasEBoot_memcmp ((void *) (VasEBoot_addr_t) *entry_ptr, "FACP", 4) == 0)
|
||||
{
|
||||
struct VasEBoot_acpi_fadt *fadt
|
||||
= ((struct VasEBoot_acpi_fadt *) (VasEBoot_addr_t) *entry_ptr);
|
||||
struct VasEBoot_acpi_table_header *dsdt
|
||||
= (struct VasEBoot_acpi_table_header *) (VasEBoot_addr_t) fadt->dsdt_addr;
|
||||
VasEBoot_uint8_t *buf = (VasEBoot_uint8_t *) dsdt;
|
||||
|
||||
port = fadt->pm1a;
|
||||
|
||||
VasEBoot_dprintf ("acpi", "PM1a port=%x\n", port);
|
||||
|
||||
if (VasEBoot_memcmp (dsdt->signature, "DSDT",
|
||||
sizeof (dsdt->signature)) == 0
|
||||
&& sleep_type < 0)
|
||||
sleep_type = get_sleep_type (buf, NULL, buf + dsdt->length,
|
||||
NULL, 0);
|
||||
}
|
||||
else if (VasEBoot_memcmp ((void *) (VasEBoot_addr_t) *entry_ptr, "SSDT", 4) == 0
|
||||
&& sleep_type < 0)
|
||||
{
|
||||
struct VasEBoot_acpi_table_header *ssdt
|
||||
= (struct VasEBoot_acpi_table_header *) (VasEBoot_addr_t) *entry_ptr;
|
||||
VasEBoot_uint8_t *buf = (VasEBoot_uint8_t *) ssdt;
|
||||
|
||||
VasEBoot_dprintf ("acpi", "SSDT = %p\n", ssdt);
|
||||
|
||||
sleep_type = get_sleep_type (buf, NULL, buf + ssdt->length, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
VasEBoot_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n", sleep_type, port);
|
||||
if (port && sleep_type >= 0 && sleep_type < 8)
|
||||
VasEBoot_outw (VAS_EBOOT_ACPI_SLP_EN | (sleep_type << VAS_EBOOT_ACPI_SLP_TYP_OFFSET),
|
||||
port & 0xffff);
|
||||
|
||||
VasEBoot_millisleep (1500);
|
||||
|
||||
/* TRANSLATORS: It's computer shutdown using ACPI, not disabling ACPI. */
|
||||
VasEBoot_puts_ (N_("ACPI shutdown failed"));
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2020, 2022 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2020, 2022, 2025 IBM Corporation
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/crypto.h>
|
||||
#include <libtasn1.h>
|
||||
|
||||
extern asn1_node VasEBoot_gnutls_gnutls_asn;
|
||||
extern asn1_node VasEBoot_gnutls_pkix_asn;
|
||||
|
||||
#define VAS_EBOOT_MAX_OID_LEN 32
|
||||
|
||||
/* RSA public key. */
|
||||
#define VAS_EBOOT_MAX_MPI 2
|
||||
#define VAS_EBOOT_RSA_PK_MODULUS 0
|
||||
#define VAS_EBOOT_RSA_PK_EXPONENT 1
|
||||
|
||||
/* Certificate fingerprint. */
|
||||
#define VAS_EBOOT_MAX_FINGERPRINT 3
|
||||
#define VAS_EBOOT_FINGERPRINT_SHA256 0
|
||||
#define VAS_EBOOT_FINGERPRINT_SHA384 1
|
||||
#define VAS_EBOOT_FINGERPRINT_SHA512 2
|
||||
|
||||
/* Max size of hash data. */
|
||||
#define VAS_EBOOT_MAX_HASH_LEN 64
|
||||
|
||||
/*
|
||||
* One or more x509 certificates. We do limited parsing:
|
||||
* extracting only the version, serial, issuer, subject, RSA public key
|
||||
* and key size.
|
||||
* Also, hold the sha256, sha384, and sha512 fingerprint of the certificate.
|
||||
*/
|
||||
struct x509_certificate
|
||||
{
|
||||
struct x509_certificate *next;
|
||||
VasEBoot_uint8_t version;
|
||||
VasEBoot_uint8_t *serial;
|
||||
VasEBoot_size_t serial_len;
|
||||
char *issuer;
|
||||
VasEBoot_size_t issuer_len;
|
||||
char *subject;
|
||||
VasEBoot_size_t subject_len;
|
||||
/* We only support RSA public keys. This encodes [modulus, publicExponent]. */
|
||||
gcry_mpi_t mpis[VAS_EBOOT_MAX_MPI];
|
||||
VasEBoot_int32_t modulus_size;
|
||||
VasEBoot_uint8_t fingerprint[VAS_EBOOT_MAX_FINGERPRINT][VAS_EBOOT_MAX_HASH_LEN];
|
||||
};
|
||||
typedef struct x509_certificate VasEBoot_x509_cert_t;
|
||||
|
||||
/* A PKCS#7 signed data signer info. */
|
||||
struct pkcs7_signer
|
||||
{
|
||||
const gcry_md_spec_t *hash;
|
||||
gcry_mpi_t sig_mpi;
|
||||
};
|
||||
typedef struct pkcs7_signer VasEBoot_pkcs7_signer_t;
|
||||
|
||||
/*
|
||||
* A PKCS#7 signed data message. We make no attempt to match intelligently, so
|
||||
* we don't save any info about the signer.
|
||||
*/
|
||||
struct pkcs7_data
|
||||
{
|
||||
VasEBoot_int32_t signer_count;
|
||||
VasEBoot_pkcs7_signer_t *signers;
|
||||
};
|
||||
typedef struct pkcs7_data VasEBoot_pkcs7_data_t;
|
||||
|
||||
/*
|
||||
* Import a DER-encoded certificate at 'data', of size 'size'. Place the results
|
||||
* into 'results', which must be already allocated.
|
||||
*/
|
||||
extern VasEBoot_err_t
|
||||
VasEBoot_x509_cert_parse (const void *data, VasEBoot_size_t size, VasEBoot_x509_cert_t *results);
|
||||
|
||||
/*
|
||||
* Release all the storage associated with the x509 certificate. If the caller
|
||||
* dynamically allocated the certificate, it must free it. The caller is also
|
||||
* responsible for maintenance of the linked list.
|
||||
*/
|
||||
extern void
|
||||
VasEBoot_x509_cert_release (VasEBoot_x509_cert_t *cert);
|
||||
|
||||
/*
|
||||
* Parse a PKCS#7 message, which must be a signed data message. The message must
|
||||
* be in 'sigbuf' and of size 'data_size'. The result is placed in 'msg', which
|
||||
* must already be allocated.
|
||||
*/
|
||||
extern VasEBoot_err_t
|
||||
VasEBoot_pkcs7_data_parse (const void *sigbuf, VasEBoot_size_t data_size, VasEBoot_pkcs7_data_t *msg);
|
||||
|
||||
/*
|
||||
* Release all the storage associated with the PKCS#7 message. If the caller
|
||||
* dynamically allocated the message, it must free it.
|
||||
*/
|
||||
extern void
|
||||
VasEBoot_pkcs7_data_release (VasEBoot_pkcs7_data_t *msg);
|
||||
|
||||
/* Do libtasn1 init. */
|
||||
extern int
|
||||
VasEBoot_asn1_init (void);
|
||||
|
||||
/*
|
||||
* Read a value from an ASN1 node, allocating memory to store it. It will work
|
||||
* for anything where the size libtasn1 returns is right:
|
||||
* - Integers
|
||||
* - Octet strings
|
||||
* - DER encoding of other structures
|
||||
*
|
||||
* It will _not_ work for things where libtasn1 size requires adjustment:
|
||||
* - Strings that require an extra null byte at the end
|
||||
* - Bit strings because libtasn1 returns the length in bits, not bytes.
|
||||
*
|
||||
* If the function returns a non-NULL value, the caller must free it.
|
||||
*/
|
||||
extern void *
|
||||
VasEBoot_asn1_allocate_and_read (asn1_node node, const char *name, const char *friendly_name,
|
||||
VasEBoot_int32_t *content_size);
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2020, 2022 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2020, 2022, 2025 IBM Corporation
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libtasn1.h>
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/err.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/crypto.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/gcrypt/gcrypt.h>
|
||||
|
||||
#include "appendedsig.h"
|
||||
|
||||
asn1_node VasEBoot_gnutls_gnutls_asn = NULL;
|
||||
asn1_node VasEBoot_gnutls_pkix_asn = NULL;
|
||||
|
||||
extern const asn1_static_node VasEBoot_gnutls_asn1_tab[];
|
||||
extern const asn1_static_node VasEBoot_pkix_asn1_tab[];
|
||||
|
||||
/*
|
||||
* Read a value from an ASN1 node, allocating memory to store it. It will work
|
||||
* for anything where the size libtasn1 returns is right:
|
||||
* - Integers
|
||||
* - Octet strings
|
||||
* - DER encoding of other structures
|
||||
*
|
||||
* It will _not_ work for things where libtasn1 size requires adjustment:
|
||||
* - Strings that require an extra NULL byte at the end
|
||||
* - Bit strings because libtasn1 returns the length in bits, not bytes.
|
||||
*
|
||||
* If the function returns a non-NULL value, the caller must free it.
|
||||
*/
|
||||
void *
|
||||
VasEBoot_asn1_allocate_and_read (asn1_node node, const char *name, const char *friendly_name,
|
||||
VasEBoot_int32_t *content_size)
|
||||
{
|
||||
VasEBoot_int32_t result;
|
||||
VasEBoot_uint8_t *tmpstr = NULL;
|
||||
VasEBoot_int32_t tmpstr_size = 0;
|
||||
|
||||
result = asn1_read_value (node, name, NULL, &tmpstr_size);
|
||||
if (result != ASN1_MEM_ERROR)
|
||||
{
|
||||
VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "reading size of %s did not return expected status: %s",
|
||||
friendly_name, asn1_strerror (result)) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmpstr = VasEBoot_malloc (tmpstr_size);
|
||||
if (tmpstr == NULL)
|
||||
{
|
||||
VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY, "could not allocate memory to store %s",
|
||||
friendly_name) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = asn1_read_value (node, name, tmpstr, &tmpstr_size);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
VasEBoot_free (tmpstr);
|
||||
VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading %s: %s", friendly_name,
|
||||
asn1_strerror (result)) ;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*content_size = tmpstr_size;
|
||||
|
||||
return tmpstr;
|
||||
}
|
||||
|
||||
int
|
||||
VasEBoot_asn1_init (void)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = asn1_array2tree (VasEBoot_gnutls_asn1_tab, &VasEBoot_gnutls_gnutls_asn, NULL);
|
||||
if (res != ASN1_SUCCESS)
|
||||
return res;
|
||||
|
||||
res = asn1_array2tree (VasEBoot_pkix_asn1_tab, &VasEBoot_gnutls_pkix_asn, NULL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
#include <VasEBoot/mm.h>
|
||||
#include <libtasn1.h>
|
||||
|
||||
/*
|
||||
* Imported from gnutls.asn.
|
||||
* https://github.com/gnutls/gnutls/blob/master/lib/gnutls.asn
|
||||
*/
|
||||
const asn1_static_node VasEBoot_gnutls_asn1_tab[] = {
|
||||
{ "GNUTLS", 536872976, NULL },
|
||||
{ NULL, 1073741836, NULL },
|
||||
{ "RSAPublicKey", 1610612741, NULL },
|
||||
{ "modulus", 1073741827, NULL },
|
||||
{ "publicExponent", 3, NULL },
|
||||
{ "RSAPrivateKey", 1610612741, NULL },
|
||||
{ "version", 1073741827, NULL },
|
||||
{ "modulus", 1073741827, NULL },
|
||||
{ "publicExponent", 1073741827, NULL },
|
||||
{ "privateExponent", 1073741827, NULL },
|
||||
{ "prime1", 1073741827, NULL },
|
||||
{ "prime2", 1073741827, NULL },
|
||||
{ "exponent1", 1073741827, NULL },
|
||||
{ "exponent2", 1073741827, NULL },
|
||||
{ "coefficient", 1073741827, NULL },
|
||||
{ "otherPrimeInfos", 16386, "OtherPrimeInfos"},
|
||||
{ "ProvableSeed", 1610612741, NULL },
|
||||
{ "algorithm", 1073741836, NULL },
|
||||
{ "seed", 7, NULL },
|
||||
{ "OtherPrimeInfos", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "OtherPrimeInfo"},
|
||||
{ "OtherPrimeInfo", 1610612741, NULL },
|
||||
{ "prime", 1073741827, NULL },
|
||||
{ "exponent", 1073741827, NULL },
|
||||
{ "coefficient", 3, NULL },
|
||||
{ "AlgorithmIdentifier", 1610612741, NULL },
|
||||
{ "algorithm", 1073741836, NULL },
|
||||
{ "parameters", 541081613, NULL },
|
||||
{ "algorithm", 1, NULL },
|
||||
{ "DigestInfo", 1610612741, NULL },
|
||||
{ "digestAlgorithm", 1073741826, "DigestAlgorithmIdentifier"},
|
||||
{ "digest", 7, NULL },
|
||||
{ "DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "DSAPublicKey", 1073741827, NULL },
|
||||
{ "DSAParameters", 1610612741, NULL },
|
||||
{ "p", 1073741827, NULL },
|
||||
{ "q", 1073741827, NULL },
|
||||
{ "g", 3, NULL },
|
||||
{ "DSASignatureValue", 1610612741, NULL },
|
||||
{ "r", 1073741827, NULL },
|
||||
{ "s", 3, NULL },
|
||||
{ "DSAPrivateKey", 1610612741, NULL },
|
||||
{ "version", 1073741827, NULL },
|
||||
{ "p", 1073741827, NULL },
|
||||
{ "q", 1073741827, NULL },
|
||||
{ "g", 1073741827, NULL },
|
||||
{ "Y", 1073741827, NULL },
|
||||
{ "priv", 3, NULL },
|
||||
{ "DHParameter", 1610612741, NULL },
|
||||
{ "prime", 1073741827, NULL },
|
||||
{ "base", 1073741827, NULL },
|
||||
{ "privateValueLength", 16387, NULL },
|
||||
{ "pkcs-11-ec-Parameters", 1610612754, NULL },
|
||||
{ "oId", 1073741836, NULL },
|
||||
{ "curveName", 31, NULL },
|
||||
{ "ECParameters", 1610612754, NULL },
|
||||
{ "namedCurve", 12, NULL },
|
||||
{ "ECPrivateKey", 1610612741, NULL },
|
||||
{ "Version", 1073741827, NULL },
|
||||
{ "privateKey", 1073741831, NULL },
|
||||
{ "parameters", 1610637314, "ECParameters"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "publicKey", 536895494, NULL },
|
||||
{ NULL, 2056, "1"},
|
||||
{ "PrincipalName", 1610612741, NULL },
|
||||
{ "name-type", 1610620931, NULL },
|
||||
{ NULL, 2056, "0"},
|
||||
{ "name-string", 536879115, NULL },
|
||||
{ NULL, 1073743880, "1"},
|
||||
{ NULL, 27, NULL },
|
||||
{ "KRB5PrincipalName", 1610612741, NULL },
|
||||
{ "realm", 1610620955, NULL },
|
||||
{ NULL, 2056, "0"},
|
||||
{ "principalName", 536879106, "PrincipalName"},
|
||||
{ NULL, 2056, "1"},
|
||||
{ "RSAPSSParameters", 1610612741, NULL },
|
||||
{ "hashAlgorithm", 1610637314, "AlgorithmIdentifier"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "maskGenAlgorithm", 1610637314, "AlgorithmIdentifier"},
|
||||
{ NULL, 2056, "1"},
|
||||
{ "saltLength", 1610653699, NULL },
|
||||
{ NULL, 1073741833, "20"},
|
||||
{ NULL, 2056, "2"},
|
||||
{ "trailerField", 536911875, NULL },
|
||||
{ NULL, 1073741833, "1"},
|
||||
{ NULL, 2056, "3"},
|
||||
{ "RSAOAEPParameters", 1610612741, NULL },
|
||||
{ "hashAlgorithm", 1610637314, "AlgorithmIdentifier"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "maskGenAlgorithm", 1610637314, "AlgorithmIdentifier"},
|
||||
{ NULL, 2056, "1"},
|
||||
{ "pSourceFunc", 536895490, "AlgorithmIdentifier"},
|
||||
{ NULL, 2056, "2"},
|
||||
{ "GOSTParameters", 1610612741, NULL },
|
||||
{ "publicKeyParamSet", 1073741836, NULL },
|
||||
{ "digestParamSet", 16396, NULL },
|
||||
{ "GOSTParametersOld", 1610612741, NULL },
|
||||
{ "publicKeyParamSet", 1073741836, NULL },
|
||||
{ "digestParamSet", 1073741836, NULL },
|
||||
{ "encryptionParamSet", 16396, NULL },
|
||||
{ "GOSTPrivateKey", 1073741831, NULL },
|
||||
{ "GOSTPrivateKeyOld", 1073741827, NULL },
|
||||
{ "IssuerSignTool", 1610612741, NULL },
|
||||
{ "signTool", 1073741858, NULL },
|
||||
{ "cATool", 1073741858, NULL },
|
||||
{ "signToolCert", 1073741858, NULL },
|
||||
{ "cAToolCert", 34, NULL },
|
||||
{ "Gost28147-89-EncryptedKey", 1610612741, NULL },
|
||||
{ "encryptedKey", 1073741831, NULL },
|
||||
{ "maskKey", 1610637319, NULL },
|
||||
{ NULL, 4104, "0"},
|
||||
{ "macKey", 7, NULL },
|
||||
{ "SubjectPublicKeyInfo", 1610612741, NULL },
|
||||
{ "algorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "subjectPublicKey", 6, NULL },
|
||||
{ "GostR3410-TransportParameters", 1610612741, NULL },
|
||||
{ "encryptionParamSet", 1073741836, NULL },
|
||||
{ "ephemeralPublicKey", 1610637314, "SubjectPublicKeyInfo"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "ukm", 7, NULL },
|
||||
{ "GostR3410-KeyTransport", 1610612741, NULL },
|
||||
{ "sessionEncryptedKey", 1073741826, "Gost28147-89-EncryptedKey"},
|
||||
{ "transportParameters", 536895490, "GostR3410-TransportParameters"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "TPMKey", 1610612741, NULL },
|
||||
{ "type", 1073741836, NULL },
|
||||
{ "emptyAuth", 1610637316, NULL },
|
||||
{ NULL, 2056, "0"},
|
||||
{ "parent", 1073741827, NULL },
|
||||
{ "pubkey", 1073741831, NULL },
|
||||
{ "privkey", 7, NULL },
|
||||
{ "MLDSAPrivateKey", 536870917, NULL },
|
||||
{ "version", 1073741827, NULL },
|
||||
{ "privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "privateKey", 1073741831, NULL },
|
||||
{ "publicKey", 536895495, NULL },
|
||||
{ NULL, 2056, "1"},
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
|
@ -0,0 +1,452 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2020, 2022 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2020, 2022, 2025 IBM Corporation
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "appendedsig.h"
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/crypto.h>
|
||||
#include <VasEBoot/gcrypt/gcrypt.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
static char asn1_error[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
|
||||
|
||||
/* RFC 5652 s 5.1. */
|
||||
static const char *signedData_oid = "1.2.840.113549.1.7.2";
|
||||
|
||||
/* RFC 4055 s 2.1. */
|
||||
static const char *sha256_oid = "2.16.840.1.101.3.4.2.1";
|
||||
static const char *sha512_oid = "2.16.840.1.101.3.4.2.3";
|
||||
|
||||
static VasEBoot_err_t
|
||||
process_content (VasEBoot_uint8_t *content, VasEBoot_int32_t size, VasEBoot_pkcs7_data_t *msg)
|
||||
{
|
||||
VasEBoot_int32_t res;
|
||||
asn1_node signed_part;
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_NONE;
|
||||
char algo_oid[VAS_EBOOT_MAX_OID_LEN];
|
||||
VasEBoot_int32_t algo_oid_size;
|
||||
VasEBoot_int32_t algo_count;
|
||||
VasEBoot_int32_t signer_count;
|
||||
VasEBoot_int32_t i;
|
||||
char version;
|
||||
VasEBoot_int32_t version_size = sizeof (version);
|
||||
VasEBoot_uint8_t *result_buf;
|
||||
VasEBoot_int32_t result_size = 0;
|
||||
VasEBoot_int32_t crls_size = 0;
|
||||
gcry_error_t gcry_err;
|
||||
bool sha256_in_da, sha256_in_si, sha512_in_da, sha512_in_si;
|
||||
char *da_path;
|
||||
char *si_sig_path;
|
||||
char *si_da_path;
|
||||
|
||||
res = asn1_create_element (VasEBoot_gnutls_pkix_asn, "PKIX1.pkcs-7-SignedData", &signed_part);
|
||||
if (res != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not create ASN.1 structure for PKCS#7 signed part");
|
||||
|
||||
res = asn1_der_decoding2 (&signed_part, content, &size,
|
||||
ASN1_DECODE_FLAG_STRICT_DER, asn1_error);
|
||||
if (res != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"error reading PKCS#7 signed data: %s", asn1_error);
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
/*
|
||||
* SignedData ::= SEQUENCE {
|
||||
* version CMSVersion,
|
||||
* digestAlgorithms DigestAlgorithmIdentifiers,
|
||||
* encapContentInfo EncapsulatedContentInfo,
|
||||
* certificates [0] IMPLICIT CertificateSet OPTIONAL,
|
||||
* crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
|
||||
* signerInfos SignerInfos }
|
||||
*/
|
||||
|
||||
res = asn1_read_value (signed_part, "version", &version, &version_size);
|
||||
if (res != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE, "error reading signedData version: %s",
|
||||
asn1_strerror (res));
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
/* Signature version must be 1 because appended signature only support v1. */
|
||||
if (version != 1)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"unexpected signature version v%d, only v1 supported", version);
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
/*
|
||||
* digestAlgorithms DigestAlgorithmIdentifiers
|
||||
*
|
||||
* DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
|
||||
* DigestAlgorithmIdentifer is an X.509 AlgorithmIdentifier (10.1.1)
|
||||
*
|
||||
* RFC 4055 s 2.1:
|
||||
* sha256Identifier AlgorithmIdentifier ::= { id-sha256, NULL }
|
||||
* sha512Identifier AlgorithmIdentifier ::= { id-sha512, NULL }
|
||||
*
|
||||
* We only support 1 element in the set, and we do not check parameters atm.
|
||||
*/
|
||||
res = asn1_number_of_elements (signed_part, "digestAlgorithms", &algo_count);
|
||||
if (res != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE, "error counting number of digest algorithms: %s",
|
||||
asn1_strerror (res));
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
if (algo_count <= 0)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE, "a minimum of 1 digest algorithm is required");
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
if (algo_count > 2)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_NOT_IMPLEMENTED_YET, "a maximum of 2 digest algorithms is supported");
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
sha256_in_da = false;
|
||||
sha512_in_da = false;
|
||||
|
||||
for (i = 0; i < algo_count; i++)
|
||||
{
|
||||
da_path = VasEBoot_xasprintf ("digestAlgorithms.?%d.algorithm", i + 1);
|
||||
if (da_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not allocate path for digest algorithm parsing path");
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
algo_oid_size = sizeof (algo_oid);
|
||||
res = asn1_read_value (signed_part, da_path, algo_oid, &algo_oid_size);
|
||||
if (res != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE, "error reading digest algorithm: %s",
|
||||
asn1_strerror (res));
|
||||
VasEBoot_free (da_path);
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
if (VasEBoot_strncmp (sha512_oid, algo_oid, algo_oid_size) == 0)
|
||||
{
|
||||
if (sha512_in_da == false)
|
||||
sha512_in_da = true;
|
||||
else
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"SHA-512 specified twice in digest algorithm list");
|
||||
VasEBoot_free (da_path);
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
}
|
||||
else if (VasEBoot_strncmp (sha256_oid, algo_oid, algo_oid_size) == 0)
|
||||
{
|
||||
if (sha256_in_da == false)
|
||||
sha256_in_da = true;
|
||||
else
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"SHA-256 specified twice in digest algorithm list");
|
||||
VasEBoot_free (da_path);
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_NOT_IMPLEMENTED_YET,
|
||||
"only SHA-256 and SHA-512 hashes are supported, found OID %s",
|
||||
algo_oid);
|
||||
VasEBoot_free (da_path);
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
VasEBoot_free (da_path);
|
||||
}
|
||||
|
||||
/* At this point, at least one of sha{256,512}_in_da must be true. */
|
||||
|
||||
/*
|
||||
* We ignore the certificates, but we don't permit CRLs. A CRL entry might be
|
||||
* revoking the certificate we're using, and we have no way of dealing with
|
||||
* that at the moment.
|
||||
*/
|
||||
res = asn1_read_value (signed_part, "crls", NULL, &crls_size);
|
||||
if (res != ASN1_ELEMENT_NOT_FOUND)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_NOT_IMPLEMENTED_YET,
|
||||
"PKCS#7 messages with embedded CRLs are not supported");
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
/* Read the signatures */
|
||||
res = asn1_number_of_elements (signed_part, "signerInfos", &signer_count);
|
||||
if (res != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE, "error counting number of signers: %s",
|
||||
asn1_strerror (res));
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
if (signer_count <= 0)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE, "a minimum of 1 signer is required");
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
msg->signers = VasEBoot_calloc (signer_count, sizeof (VasEBoot_pkcs7_signer_t));
|
||||
if (msg->signers == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not allocate space for %d signers", signer_count);
|
||||
goto cleanup_signed_part;
|
||||
}
|
||||
|
||||
msg->signer_count = 0;
|
||||
for (i = 0; i < signer_count; i++)
|
||||
{
|
||||
si_da_path = VasEBoot_xasprintf ("signerInfos.?%d.digestAlgorithm.algorithm", i + 1);
|
||||
if (si_da_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not allocate path for signer %d's digest algorithm parsing path",
|
||||
i);
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
algo_oid_size = sizeof (algo_oid);
|
||||
res = asn1_read_value (signed_part, si_da_path, algo_oid, &algo_oid_size);
|
||||
if (res != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"error reading signer %d's digest algorithm: %s", i, asn1_strerror (res));
|
||||
VasEBoot_free (si_da_path);
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
VasEBoot_free (si_da_path);
|
||||
|
||||
if (VasEBoot_strncmp (sha512_oid, algo_oid, algo_oid_size) == 0)
|
||||
{
|
||||
if (sha512_in_da == false)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"signer %d claims a SHA-512 signature which was not "
|
||||
"specified in the outer DigestAlgorithms", i);
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
else
|
||||
{
|
||||
sha512_in_si = true;
|
||||
msg->signers[i].hash = VasEBoot_crypto_lookup_md_by_name ("sha512");
|
||||
}
|
||||
}
|
||||
else if (VasEBoot_strncmp (sha256_oid, algo_oid, algo_oid_size) == 0)
|
||||
{
|
||||
if (sha256_in_da == false)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"signer %d claims a SHA-256 signature which was not "
|
||||
"specified in the outer DigestAlgorithms", i);
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
else
|
||||
{
|
||||
sha256_in_si = true;
|
||||
msg->signers[i].hash = VasEBoot_crypto_lookup_md_by_name ("sha256");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_NOT_IMPLEMENTED_YET,
|
||||
"only SHA-256 and SHA-512 hashes are supported, found OID %s",
|
||||
algo_oid);
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
if (msg->signers[i].hash == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"Hash algorithm for signer %d (OID %s) not loaded", i, algo_oid);
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
si_sig_path = VasEBoot_xasprintf ("signerInfos.?%d.signature", i + 1);
|
||||
if (si_sig_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not allocate path for signer %d's signature parsing path", i);
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
result_buf = VasEBoot_asn1_allocate_and_read (signed_part, si_sig_path, "signature data", &result_size);
|
||||
VasEBoot_free (si_sig_path);
|
||||
|
||||
if (result_buf == NULL)
|
||||
{
|
||||
err = VasEBoot_errno;
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
gcry_err = _gcry_mpi_scan (&(msg->signers[i].sig_mpi), GCRYMPI_FMT_USG,
|
||||
result_buf, result_size, NULL);
|
||||
VasEBoot_free (result_buf);
|
||||
|
||||
if (gcry_err != GPG_ERR_NO_ERROR)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"error loading signature %d into MPI structure: %d",
|
||||
i, gcry_err);
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use msg->signer_count to track fully populated signerInfos so we know
|
||||
* how many we need to clean up.
|
||||
*/
|
||||
msg->signer_count++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Final consistency check of signerInfo.*.digestAlgorithm vs digestAlgorithms
|
||||
* .*.algorithm. An algorithm must be present in both digestAlgorithms and
|
||||
* signerInfo or in neither. We have already checked for an algorithm in
|
||||
* signerInfo that is not in digestAlgorithms, here we check for algorithms in
|
||||
* digestAlgorithms but not in signerInfos.
|
||||
*/
|
||||
if (sha512_in_da == true && sha512_in_si == false)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"SHA-512 specified in DigestAlgorithms but did not appear in SignerInfos");
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
if (sha256_in_da == true && sha256_in_si == false)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"SHA-256 specified in DigestAlgorithms but did not appear in SignerInfos");
|
||||
goto cleanup_signerInfos;
|
||||
}
|
||||
|
||||
asn1_delete_structure (&signed_part);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
|
||||
cleanup_signerInfos:
|
||||
for (i = 0; i < msg->signer_count; i++)
|
||||
_gcry_mpi_release (msg->signers[i].sig_mpi);
|
||||
|
||||
VasEBoot_free (msg->signers);
|
||||
|
||||
cleanup_signed_part:
|
||||
asn1_delete_structure (&signed_part);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_pkcs7_data_parse (const void *sigbuf, VasEBoot_size_t data_size, VasEBoot_pkcs7_data_t *msg)
|
||||
{
|
||||
VasEBoot_int32_t res;
|
||||
asn1_node content_info;
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_NONE;
|
||||
char content_oid[VAS_EBOOT_MAX_OID_LEN];
|
||||
VasEBoot_uint8_t *content;
|
||||
VasEBoot_int32_t content_size;
|
||||
VasEBoot_int32_t content_oid_size = sizeof (content_oid);
|
||||
VasEBoot_int32_t size = (VasEBoot_int32_t) data_size;
|
||||
|
||||
if (data_size > VAS_EBOOT_UINT_MAX)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_RANGE,
|
||||
"cannot parse a PKCS#7 message where data size > VAS_EBOOT_UINT_MAX");
|
||||
|
||||
res = asn1_create_element (VasEBoot_gnutls_pkix_asn, "PKIX1.pkcs-7-ContentInfo", &content_info);
|
||||
if (res != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not create ASN.1 structure for PKCS#7 data: %s",
|
||||
asn1_strerror (res));
|
||||
|
||||
res = asn1_der_decoding2 (&content_info, sigbuf, &size,
|
||||
ASN1_DECODE_FLAG_STRICT_DER | ASN1_DECODE_FLAG_ALLOW_PADDING,
|
||||
asn1_error);
|
||||
if (res != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"error decoding PKCS#7 message DER: %s", asn1_error);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* ContentInfo ::= SEQUENCE {
|
||||
* contentType ContentType,
|
||||
* content [0] EXPLICIT ANY DEFINED BY contentType }
|
||||
*
|
||||
* ContentType ::= OBJECT IDENTIFIER
|
||||
*/
|
||||
res = asn1_read_value (content_info, "contentType", content_oid, &content_oid_size);
|
||||
if (res != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE, "error reading PKCS#7 content type: %s",
|
||||
asn1_strerror (res));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* OID for SignedData defined in 5.1. */
|
||||
if (VasEBoot_strncmp (signedData_oid, content_oid, content_oid_size) != 0)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_SIGNATURE,
|
||||
"unexpected content type in PKCS#7 message: OID %s", content_oid);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
content = VasEBoot_asn1_allocate_and_read (content_info, "content", "PKCS#7 message content", &content_size);
|
||||
if (content == NULL)
|
||||
{
|
||||
err = VasEBoot_errno;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
err = process_content (content, content_size, msg);
|
||||
VasEBoot_free (content);
|
||||
|
||||
cleanup:
|
||||
asn1_delete_structure (&content_info);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release all the storage associated with the PKCS#7 message. If the caller
|
||||
* dynamically allocated the message, it must free it.
|
||||
*/
|
||||
void
|
||||
VasEBoot_pkcs7_data_release (VasEBoot_pkcs7_data_t *msg)
|
||||
{
|
||||
VasEBoot_int32_t i;
|
||||
|
||||
for (i = 0; i < msg->signer_count; i++)
|
||||
_gcry_mpi_release (msg->signers[i].sig_mpi);
|
||||
|
||||
VasEBoot_free (msg->signers);
|
||||
}
|
||||
|
|
@ -0,0 +1,485 @@
|
|||
#include <VasEBoot/mm.h>
|
||||
#include <libtasn1.h>
|
||||
|
||||
/*
|
||||
* Imported from pkix.asn.
|
||||
* https://github.com/gnutls/gnutls/blob/master/lib/pkix.asn
|
||||
*/
|
||||
const asn1_static_node VasEBoot_pkix_asn1_tab[] = {
|
||||
{ "PKIX1", 536875024, NULL },
|
||||
{ NULL, 1073741836, NULL },
|
||||
{ "PrivateKeyUsagePeriod", 1610612741, NULL },
|
||||
{ "notBefore", 1610637349, NULL },
|
||||
{ NULL, 4104, "0"},
|
||||
{ "notAfter", 536895525, NULL },
|
||||
{ NULL, 4104, "1"},
|
||||
{ "AuthorityKeyIdentifier", 1610612741, NULL },
|
||||
{ "keyIdentifier", 1610637319, NULL },
|
||||
{ NULL, 4104, "0"},
|
||||
{ "authorityCertIssuer", 1610637314, "GeneralNames"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "authorityCertSerialNumber", 536895490, "CertificateSerialNumber"},
|
||||
{ NULL, 4104, "2"},
|
||||
{ "SubjectKeyIdentifier", 1073741831, NULL },
|
||||
{ "KeyUsage", 1073741830, NULL },
|
||||
{ "DirectoryString", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "SubjectAltName", 1073741826, "GeneralNames"},
|
||||
{ "GeneralNames", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "GeneralName"},
|
||||
{ "GeneralName", 1610612754, NULL },
|
||||
{ "otherName", 1610620930, "AnotherName"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "rfc822Name", 1610620957, NULL },
|
||||
{ NULL, 4104, "1"},
|
||||
{ "dNSName", 1610620957, NULL },
|
||||
{ NULL, 4104, "2"},
|
||||
{ "x400Address", 1610620941, NULL },
|
||||
{ NULL, 4104, "3"},
|
||||
{ "directoryName", 1610620939, NULL },
|
||||
{ NULL, 1073743880, "4"},
|
||||
{ NULL, 2, "RelativeDistinguishedName"},
|
||||
{ "ediPartyName", 1610620941, NULL },
|
||||
{ NULL, 4104, "5"},
|
||||
{ "uniformResourceIdentifier", 1610620957, NULL },
|
||||
{ NULL, 4104, "6"},
|
||||
{ "iPAddress", 1610620935, NULL },
|
||||
{ NULL, 4104, "7"},
|
||||
{ "registeredID", 536879116, NULL },
|
||||
{ NULL, 4104, "8"},
|
||||
{ "AnotherName", 1610612741, NULL },
|
||||
{ "type-id", 1073741836, NULL },
|
||||
{ "value", 541073421, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "type-id", 1, NULL },
|
||||
{ "IssuerAltName", 1073741826, "GeneralNames"},
|
||||
{ "BasicConstraints", 1610612741, NULL },
|
||||
{ "cA", 1610645508, NULL },
|
||||
{ NULL, 131081, NULL },
|
||||
{ "pathLenConstraint", 16387, NULL },
|
||||
{ "CRLDistributionPoints", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "DistributionPoint"},
|
||||
{ "DistributionPoint", 1610612741, NULL },
|
||||
{ "distributionPoint", 1610637314, "DistributionPointName"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "reasons", 1610637314, "ReasonFlags"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "cRLIssuer", 536895490, "GeneralNames"},
|
||||
{ NULL, 4104, "2"},
|
||||
{ "DistributionPointName", 1610612754, NULL },
|
||||
{ "fullName", 1610620930, "GeneralNames"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "nameRelativeToCRLIssuer", 536879106, "RelativeDistinguishedName"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "ReasonFlags", 1073741830, NULL },
|
||||
{ "ExtKeyUsageSyntax", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 12, NULL },
|
||||
{ "AuthorityInfoAccessSyntax", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "AccessDescription"},
|
||||
{ "AccessDescription", 1610612741, NULL },
|
||||
{ "accessMethod", 1073741836, NULL },
|
||||
{ "accessLocation", 2, "GeneralName"},
|
||||
{ "Attribute", 1610612741, NULL },
|
||||
{ "type", 1073741836, NULL },
|
||||
{ "values", 536870927, NULL },
|
||||
{ NULL, 13, NULL },
|
||||
{ "AttributeTypeAndValue", 1610612741, NULL },
|
||||
{ "type", 1073741836, NULL },
|
||||
{ "value", 13, NULL },
|
||||
{ "Name", 1610612754, NULL },
|
||||
{ "rdnSequence", 536870923, NULL },
|
||||
{ NULL, 2, "RelativeDistinguishedName"},
|
||||
{ "DistinguishedName", 1610612747, NULL },
|
||||
{ NULL, 2, "RelativeDistinguishedName"},
|
||||
{ "RelativeDistinguishedName", 1612709903, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "AttributeTypeAndValue"},
|
||||
{ "Certificate", 1610612741, NULL },
|
||||
{ "tbsCertificate", 1073741826, "TBSCertificate"},
|
||||
{ "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signature", 6, NULL },
|
||||
{ "TBSCertificate", 1610612741, NULL },
|
||||
{ "version", 1610653699, NULL },
|
||||
{ NULL, 1073741833, "0"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "serialNumber", 1073741826, "CertificateSerialNumber"},
|
||||
{ "signature", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "issuer", 1073741826, "Name"},
|
||||
{ "validity", 1073741826, "Validity"},
|
||||
{ "subject", 1073741826, "Name"},
|
||||
{ "subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"},
|
||||
{ "issuerUniqueID", 1610637314, "UniqueIdentifier"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "subjectUniqueID", 1610637314, "UniqueIdentifier"},
|
||||
{ NULL, 4104, "2"},
|
||||
{ "extensions", 536895490, "Extensions"},
|
||||
{ NULL, 2056, "3"},
|
||||
{ "CertificateSerialNumber", 1073741827, NULL },
|
||||
{ "Validity", 1610612741, NULL },
|
||||
{ "notBefore", 1073741826, "Time"},
|
||||
{ "notAfter", 2, "Time"},
|
||||
{ "Time", 1610612754, NULL },
|
||||
{ "utcTime", 1073741860, NULL },
|
||||
{ "generalTime", 37, NULL },
|
||||
{ "UniqueIdentifier", 1073741830, NULL },
|
||||
{ "SubjectPublicKeyInfo", 1610612741, NULL },
|
||||
{ "algorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "subjectPublicKey", 6, NULL },
|
||||
{ "Extensions", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "Extension"},
|
||||
{ "Extension", 1610612741, NULL },
|
||||
{ "extnID", 1073741836, NULL },
|
||||
{ "critical", 1610645508, NULL },
|
||||
{ NULL, 131081, NULL },
|
||||
{ "extnValue", 7, NULL },
|
||||
{ "CertificateList", 1610612741, NULL },
|
||||
{ "tbsCertList", 1073741826, "TBSCertList"},
|
||||
{ "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signature", 6, NULL },
|
||||
{ "TBSCertList", 1610612741, NULL },
|
||||
{ "version", 1073758211, NULL },
|
||||
{ "signature", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "issuer", 1073741826, "Name"},
|
||||
{ "thisUpdate", 1073741826, "Time"},
|
||||
{ "nextUpdate", 1073758210, "Time"},
|
||||
{ "revokedCertificates", 1610629131, NULL },
|
||||
{ NULL, 536870917, NULL },
|
||||
{ "userCertificate", 1073741826, "CertificateSerialNumber"},
|
||||
{ "revocationDate", 1073741826, "Time"},
|
||||
{ "crlEntryExtensions", 16386, "Extensions"},
|
||||
{ "crlExtensions", 536895490, "Extensions"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "AlgorithmIdentifier", 1610612741, NULL },
|
||||
{ "algorithm", 1073741836, NULL },
|
||||
{ "parameters", 541081613, NULL },
|
||||
{ "algorithm", 1, NULL },
|
||||
{ "Dss-Sig-Value", 1610612741, NULL },
|
||||
{ "r", 1073741827, NULL },
|
||||
{ "s", 3, NULL },
|
||||
{ "Dss-Parms", 1610612741, NULL },
|
||||
{ "p", 1073741827, NULL },
|
||||
{ "q", 1073741827, NULL },
|
||||
{ "g", 3, NULL },
|
||||
{ "pkcs-7-ContentInfo", 1610612741, NULL },
|
||||
{ "contentType", 1073741836, NULL },
|
||||
{ "content", 541073421, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "contentType", 1, NULL },
|
||||
{ "pkcs-7-DigestInfo", 1610612741, NULL },
|
||||
{ "digestAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "digest", 7, NULL },
|
||||
{ "pkcs-7-SignedData", 1610612741, NULL },
|
||||
{ "version", 1073741827, NULL },
|
||||
{ "digestAlgorithms", 1073741826, "pkcs-7-DigestAlgorithmIdentifiers"},
|
||||
{ "encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"},
|
||||
{ "certificates", 1610637314, "pkcs-7-CertificateSet"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "crls", 1610637314, "pkcs-7-CertificateRevocationLists"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "signerInfos", 2, "pkcs-7-SignerInfos"},
|
||||
{ "pkcs-7-DigestAlgorithmIdentifiers", 1610612751, NULL },
|
||||
{ NULL, 2, "AlgorithmIdentifier"},
|
||||
{ "pkcs-7-EncapsulatedContentInfo", 1610612741, NULL },
|
||||
{ "eContentType", 1073741836, NULL },
|
||||
{ "eContent", 536895501, NULL },
|
||||
{ NULL, 2056, "0"},
|
||||
{ "pkcs-7-CertificateRevocationLists", 1610612751, NULL },
|
||||
{ NULL, 13, NULL },
|
||||
{ "pkcs-7-CertificateChoices", 1610612754, NULL },
|
||||
{ "certificate", 13, NULL },
|
||||
{ "pkcs-7-CertificateSet", 1610612751, NULL },
|
||||
{ NULL, 2, "pkcs-7-CertificateChoices"},
|
||||
{ "IssuerAndSerialNumber", 1610612741, NULL },
|
||||
{ "issuer", 1073741826, "Name"},
|
||||
{ "serialNumber", 2, "CertificateSerialNumber"},
|
||||
{ "pkcs-7-SignerInfo", 1610612741, NULL },
|
||||
{ "version", 1073741827, NULL },
|
||||
{ "sid", 1073741826, "SignerIdentifier"},
|
||||
{ "digestAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signedAttrs", 1610637314, "SignedAttributes"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signature", 1073741831, NULL },
|
||||
{ "unsignedAttrs", 536895490, "SignedAttributes"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "SignedAttributes", 1612709903, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "Attribute"},
|
||||
{ "SignerIdentifier", 1610612754, NULL },
|
||||
{ "issuerAndSerialNumber", 1073741826, "IssuerAndSerialNumber"},
|
||||
{ "subjectKeyIdentifier", 536879111, NULL },
|
||||
{ NULL, 4104, "0"},
|
||||
{ "pkcs-7-SignerInfos", 1610612751, NULL },
|
||||
{ NULL, 2, "pkcs-7-SignerInfo"},
|
||||
{ "pkcs-10-CertificationRequestInfo", 1610612741, NULL },
|
||||
{ "version", 1073741827, NULL },
|
||||
{ "subject", 1073741826, "Name"},
|
||||
{ "subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"},
|
||||
{ "attributes", 536879106, "Attributes"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "Attributes", 1610612751, NULL },
|
||||
{ NULL, 2, "Attribute"},
|
||||
{ "pkcs-10-CertificationRequest", 1610612741, NULL },
|
||||
{ "certificationRequestInfo", 1073741826, "pkcs-10-CertificationRequestInfo"},
|
||||
{ "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signature", 6, NULL },
|
||||
{ "pkcs-9-at-challengePassword", 1879048204, NULL },
|
||||
{ "iso", 1073741825, "1"},
|
||||
{ "member-body", 1073741825, "2"},
|
||||
{ "us", 1073741825, "840"},
|
||||
{ "rsadsi", 1073741825, "113549"},
|
||||
{ "pkcs", 1073741825, "1"},
|
||||
{ NULL, 1073741825, "9"},
|
||||
{ NULL, 1, "7"},
|
||||
{ "pkcs-9-challengePassword", 1610612754, NULL },
|
||||
{ "printableString", 1073741855, NULL },
|
||||
{ "utf8String", 34, NULL },
|
||||
{ "pkcs-9-localKeyId", 1073741831, NULL },
|
||||
{ "pkcs-8-PrivateKeyInfo", 1610612741, NULL },
|
||||
{ "version", 1073741827, NULL },
|
||||
{ "privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "privateKey", 1073741831, NULL },
|
||||
{ "attributes", 536895490, "Attributes"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "pkcs-8-EncryptedPrivateKeyInfo", 1610612741, NULL },
|
||||
{ "encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "encryptedData", 2, "pkcs-8-EncryptedData"},
|
||||
{ "pkcs-8-EncryptedData", 1073741831, NULL },
|
||||
{ "pkcs-5-des-CBC-params", 1612709895, NULL },
|
||||
{ NULL, 1048586, "8"},
|
||||
{ "pkcs-5-des-EDE3-CBC-params", 1612709895, NULL },
|
||||
{ NULL, 1048586, "8"},
|
||||
{ "pkcs-5-aes128-CBC-params", 1612709895, NULL },
|
||||
{ NULL, 1048586, "16"},
|
||||
{ "pkcs-5-aes192-CBC-params", 1612709895, NULL },
|
||||
{ NULL, 1048586, "16"},
|
||||
{ "pkcs-5-aes256-CBC-params", 1612709895, NULL },
|
||||
{ NULL, 1048586, "16"},
|
||||
{ "Gost28147-89-Parameters", 1610612741, NULL },
|
||||
{ "iv", 1073741831, NULL },
|
||||
{ "encryptionParamSet", 12, NULL },
|
||||
{ "pkcs-5-PBE-params", 1610612741, NULL },
|
||||
{ "salt", 1073741831, NULL },
|
||||
{ "iterationCount", 3, NULL },
|
||||
{ "pkcs-5-PBES2-params", 1610612741, NULL },
|
||||
{ "keyDerivationFunc", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "encryptionScheme", 2, "AlgorithmIdentifier"},
|
||||
{ "pkcs-5-PBMAC1-params", 1610612741, NULL },
|
||||
{ "keyDerivationFunc", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "messageAuthScheme", 2, "AlgorithmIdentifier"},
|
||||
{ "pkcs-5-PBKDF2-params", 1610612741, NULL },
|
||||
{ "salt", 1610612754, NULL },
|
||||
{ "specified", 1073741831, NULL },
|
||||
{ "otherSource", 2, "AlgorithmIdentifier"},
|
||||
{ "iterationCount", 1073741827, NULL },
|
||||
{ "keyLength", 1073758211, NULL },
|
||||
{ "prf", 16386, "AlgorithmIdentifier"},
|
||||
{ "pkcs-12-PFX", 1610612741, NULL },
|
||||
{ "version", 1610874883, NULL },
|
||||
{ "v3", 1, "3"},
|
||||
{ "authSafe", 1073741826, "pkcs-7-ContentInfo"},
|
||||
{ "macData", 16386, "pkcs-12-MacData"},
|
||||
{ "pkcs-12-PbeParams", 1610612741, NULL },
|
||||
{ "salt", 1073741831, NULL },
|
||||
{ "iterations", 3, NULL },
|
||||
{ "pkcs-12-MacData", 1610612741, NULL },
|
||||
{ "mac", 1073741826, "pkcs-7-DigestInfo"},
|
||||
{ "macSalt", 1073741831, NULL },
|
||||
{ "iterations", 536903683, NULL },
|
||||
{ NULL, 9, "1"},
|
||||
{ "pkcs-12-AuthenticatedSafe", 1610612747, NULL },
|
||||
{ NULL, 2, "pkcs-7-ContentInfo"},
|
||||
{ "pkcs-12-SafeContents", 1610612747, NULL },
|
||||
{ NULL, 2, "pkcs-12-SafeBag"},
|
||||
{ "pkcs-12-SafeBag", 1610612741, NULL },
|
||||
{ "bagId", 1073741836, NULL },
|
||||
{ "bagValue", 1614815245, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "badId", 1, NULL },
|
||||
{ "bagAttributes", 536887311, NULL },
|
||||
{ NULL, 2, "Attribute"},
|
||||
{ "pkcs-12-CertBag", 1610612741, NULL },
|
||||
{ "certId", 1073741836, NULL },
|
||||
{ "certValue", 541073421, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "certId", 1, NULL },
|
||||
{ "pkcs-12-CRLBag", 1610612741, NULL },
|
||||
{ "crlId", 1073741836, NULL },
|
||||
{ "crlValue", 541073421, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "crlId", 1, NULL },
|
||||
{ "pkcs-12-SecretBag", 1610612741, NULL },
|
||||
{ "secretTypeId", 1073741836, NULL },
|
||||
{ "secretValue", 541073421, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "secretTypeId", 1, NULL },
|
||||
{ "pkcs-7-Data", 1073741831, NULL },
|
||||
{ "pkcs-7-EncryptedData", 1610612741, NULL },
|
||||
{ "version", 1073741827, NULL },
|
||||
{ "encryptedContentInfo", 1073741826, "pkcs-7-EncryptedContentInfo"},
|
||||
{ "unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "pkcs-7-EncryptedContentInfo", 1610612741, NULL },
|
||||
{ "contentType", 1073741836, NULL },
|
||||
{ "contentEncryptionAlgorithm", 1073741826, "pkcs-7-ContentEncryptionAlgorithmIdentifier"},
|
||||
{ "encryptedContent", 536895495, NULL },
|
||||
{ NULL, 4104, "0"},
|
||||
{ "pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "pkcs-7-UnprotectedAttributes", 1612709903, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "Attribute"},
|
||||
{ "ProxyCertInfo", 1610612741, NULL },
|
||||
{ "pCPathLenConstraint", 1073758211, NULL },
|
||||
{ "proxyPolicy", 2, "ProxyPolicy"},
|
||||
{ "ProxyPolicy", 1610612741, NULL },
|
||||
{ "policyLanguage", 1073741836, NULL },
|
||||
{ "policy", 16391, NULL },
|
||||
{ "certificatePolicies", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "PolicyInformation"},
|
||||
{ "PolicyInformation", 1610612741, NULL },
|
||||
{ "policyIdentifier", 1073741836, NULL },
|
||||
{ "policyQualifiers", 538984459, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "PolicyQualifierInfo"},
|
||||
{ "PolicyQualifierInfo", 1610612741, NULL },
|
||||
{ "policyQualifierId", 1073741836, NULL },
|
||||
{ "qualifier", 541065229, NULL },
|
||||
{ "policyQualifierId", 1, NULL },
|
||||
{ "CPSuri", 1073741853, NULL },
|
||||
{ "UserNotice", 1610612741, NULL },
|
||||
{ "noticeRef", 1073758210, "NoticeReference"},
|
||||
{ "explicitText", 16386, "DisplayText"},
|
||||
{ "NoticeReference", 1610612741, NULL },
|
||||
{ "organization", 1073741826, "DisplayText"},
|
||||
{ "noticeNumbers", 536870923, NULL },
|
||||
{ NULL, 3, NULL },
|
||||
{ "DisplayText", 1610612754, NULL },
|
||||
{ "ia5String", 1612709917, NULL },
|
||||
{ "200", 524298, "1"},
|
||||
{ "visibleString", 1612709923, NULL },
|
||||
{ "200", 524298, "1"},
|
||||
{ "bmpString", 1612709921, NULL },
|
||||
{ "200", 524298, "1"},
|
||||
{ "utf8String", 538968098, NULL },
|
||||
{ "200", 524298, "1"},
|
||||
{ "OCSPRequest", 1610612741, NULL },
|
||||
{ "tbsRequest", 1073741826, "TBSRequest"},
|
||||
{ "optionalSignature", 536895490, "Signature"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "TBSRequest", 1610612741, NULL },
|
||||
{ "version", 1610653699, NULL },
|
||||
{ NULL, 1073741833, "0"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "requestorName", 1610637314, "GeneralName"},
|
||||
{ NULL, 2056, "1"},
|
||||
{ "requestList", 1610612747, NULL },
|
||||
{ NULL, 2, "Request"},
|
||||
{ "requestExtensions", 536895490, "Extensions"},
|
||||
{ NULL, 2056, "2"},
|
||||
{ "Signature", 1610612741, NULL },
|
||||
{ "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signature", 1073741830, NULL },
|
||||
{ "certs", 536895499, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ NULL, 2, "Certificate"},
|
||||
{ "Request", 1610612741, NULL },
|
||||
{ "reqCert", 1073741826, "CertID"},
|
||||
{ "singleRequestExtensions", 536895490, "Extensions"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "CertID", 1610612741, NULL },
|
||||
{ "hashAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "issuerNameHash", 1073741831, NULL },
|
||||
{ "issuerKeyHash", 1073741831, NULL },
|
||||
{ "serialNumber", 2, "CertificateSerialNumber"},
|
||||
{ "OCSPResponse", 1610612741, NULL },
|
||||
{ "responseStatus", 1073741826, "OCSPResponseStatus"},
|
||||
{ "responseBytes", 536895490, "ResponseBytes"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "OCSPResponseStatus", 1610874901, NULL },
|
||||
{ "successful", 1073741825, "0"},
|
||||
{ "malformedRequest", 1073741825, "1"},
|
||||
{ "internalError", 1073741825, "2"},
|
||||
{ "tryLater", 1073741825, "3"},
|
||||
{ "sigRequired", 1073741825, "5"},
|
||||
{ "unauthorized", 1, "6"},
|
||||
{ "ResponseBytes", 1610612741, NULL },
|
||||
{ "responseType", 1073741836, NULL },
|
||||
{ "response", 7, NULL },
|
||||
{ "BasicOCSPResponse", 1610612741, NULL },
|
||||
{ "tbsResponseData", 1073741826, "ResponseData"},
|
||||
{ "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signature", 1073741830, NULL },
|
||||
{ "certs", 536895499, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ NULL, 2, "Certificate"},
|
||||
{ "ResponseData", 1610612741, NULL },
|
||||
{ "version", 1610653699, NULL },
|
||||
{ NULL, 1073741833, "0"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "responderID", 1073741826, "ResponderID"},
|
||||
{ "producedAt", 1073741861, NULL },
|
||||
{ "responses", 1610612747, NULL },
|
||||
{ NULL, 2, "SingleResponse"},
|
||||
{ "responseExtensions", 536895490, "Extensions"},
|
||||
{ NULL, 2056, "1"},
|
||||
{ "ResponderID", 1610612754, NULL },
|
||||
{ "byName", 1610620939, NULL },
|
||||
{ NULL, 1073743880, "1"},
|
||||
{ NULL, 2, "RelativeDistinguishedName"},
|
||||
{ "byKey", 536879111, NULL },
|
||||
{ NULL, 2056, "2"},
|
||||
{ "SingleResponse", 1610612741, NULL },
|
||||
{ "certID", 1073741826, "CertID"},
|
||||
{ "certStatus", 1073741826, "CertStatus"},
|
||||
{ "thisUpdate", 1073741861, NULL },
|
||||
{ "nextUpdate", 1610637349, NULL },
|
||||
{ NULL, 2056, "0"},
|
||||
{ "singleExtensions", 536895490, "Extensions"},
|
||||
{ NULL, 2056, "1"},
|
||||
{ "CertStatus", 1610612754, NULL },
|
||||
{ "good", 1610620948, NULL },
|
||||
{ NULL, 4104, "0"},
|
||||
{ "revoked", 1610620930, "RevokedInfo"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "unknown", 536879106, "UnknownInfo"},
|
||||
{ NULL, 4104, "2"},
|
||||
{ "RevokedInfo", 1610612741, NULL },
|
||||
{ "revocationTime", 1073741861, NULL },
|
||||
{ "revocationReason", 537157653, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "unspecified", 1, "0"},
|
||||
{ "UnknownInfo", 1073741844, NULL },
|
||||
{ "NameConstraints", 1610612741, NULL },
|
||||
{ "permittedSubtrees", 1610637314, "GeneralSubtrees"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "excludedSubtrees", 536895490, "GeneralSubtrees"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "GeneralSubtrees", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "GeneralSubtree"},
|
||||
{ "GeneralSubtree", 1610612741, NULL },
|
||||
{ "base", 1073741826, "GeneralName"},
|
||||
{ "minimum", 1610653699, NULL },
|
||||
{ NULL, 1073741833, "0"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "maximum", 536895491, NULL },
|
||||
{ NULL, 4104, "1"},
|
||||
{ "TlsFeatures", 536870923, NULL },
|
||||
{ NULL, 3, NULL },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
|
@ -0,0 +1,970 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2020, 2022 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2020, 2022, 2025 IBM Corporation
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libtasn1.h>
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/err.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/crypto.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/gcrypt/gcrypt.h>
|
||||
|
||||
#include "appendedsig.h"
|
||||
|
||||
static char asn1_error[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
|
||||
|
||||
|
||||
/* RFC 3279 2.3.1 RSA Keys. */
|
||||
static const char *rsaEncryption_oid = "1.2.840.113549.1.1.1";
|
||||
|
||||
/* RFC 5280 Appendix A. */
|
||||
static const char *commonName_oid = "2.5.4.3";
|
||||
|
||||
/* RFC 5280 4.2.1.3 Key Usage. */
|
||||
static const char *keyUsage_oid = "2.5.29.15";
|
||||
|
||||
static const VasEBoot_uint8_t digitalSignatureUsage = 0x80;
|
||||
|
||||
/* RFC 5280 4.2.1.9 Basic Constraints. */
|
||||
static const char *basicConstraints_oid = "2.5.29.19";
|
||||
|
||||
/* RFC 5280 4.2.1.12 Extended Key Usage. */
|
||||
static const char *extendedKeyUsage_oid = "2.5.29.37";
|
||||
static const char *codeSigningUsage_oid = "1.3.6.1.5.5.7.3.3";
|
||||
|
||||
/*
|
||||
* RFC 3279 2.3.1
|
||||
*
|
||||
* The RSA public key MUST be encoded using the ASN.1 type RSAPublicKey:
|
||||
*
|
||||
* RSAPublicKey ::= SEQUENCE {
|
||||
* modulus INTEGER, -- n
|
||||
* publicExponent INTEGER } -- e
|
||||
*
|
||||
* where modulus is the modulus n, and publicExponent is the public exponent e.
|
||||
*/
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_parse_rsa_pubkey (VasEBoot_uint8_t *der, VasEBoot_int32_t dersize, VasEBoot_x509_cert_t *certificate)
|
||||
{
|
||||
VasEBoot_int32_t result;
|
||||
asn1_node spk = NULL;
|
||||
VasEBoot_uint8_t *m_data, *e_data;
|
||||
VasEBoot_int32_t m_size, e_size;
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_NONE;
|
||||
gcry_error_t gcry_err;
|
||||
|
||||
result = asn1_create_element (VasEBoot_gnutls_gnutls_asn, "GNUTLS.RSAPublicKey", &spk);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"cannot create storage for public key ASN.1 data");
|
||||
|
||||
result = asn1_der_decoding2 (&spk, der, &dersize, ASN1_DECODE_FLAG_STRICT_DER, asn1_error);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"cannot decode certificate public key DER: %s", asn1_error);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
m_data = VasEBoot_asn1_allocate_and_read (spk, "modulus", "RSA modulus", &m_size);
|
||||
if (m_data == NULL)
|
||||
{
|
||||
err = VasEBoot_errno;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
e_data = VasEBoot_asn1_allocate_and_read (spk, "publicExponent", "RSA public exponent", &e_size);
|
||||
if (e_data == NULL)
|
||||
{
|
||||
err = VasEBoot_errno;
|
||||
goto cleanup_m_data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert m, e to mpi
|
||||
*
|
||||
* nscanned is not set for FMT_USG, it's only set for FMT_PGP, so we can't
|
||||
* verify it.
|
||||
*/
|
||||
gcry_err = _gcry_mpi_scan (&certificate->mpis[0], GCRYMPI_FMT_USG, m_data, m_size, NULL);
|
||||
if (gcry_err != GPG_ERR_NO_ERROR)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"error loading RSA modulus into MPI structure: %d", gcry_err);
|
||||
goto cleanup_e_data;
|
||||
}
|
||||
|
||||
gcry_err = _gcry_mpi_scan (&certificate->mpis[1], GCRYMPI_FMT_USG, e_data, e_size, NULL);
|
||||
if (gcry_err != GPG_ERR_NO_ERROR)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"error loading RSA exponent into MPI structure: %d", gcry_err);
|
||||
goto cleanup_m_mpi;
|
||||
}
|
||||
|
||||
/* RSA key size in bits. */
|
||||
certificate->modulus_size = (m_size * 8) - 8;
|
||||
|
||||
VasEBoot_free (e_data);
|
||||
VasEBoot_free (m_data);
|
||||
asn1_delete_structure (&spk);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
|
||||
cleanup_m_mpi:
|
||||
_gcry_mpi_release (certificate->mpis[0]);
|
||||
cleanup_e_data:
|
||||
VasEBoot_free (e_data);
|
||||
cleanup_m_data:
|
||||
VasEBoot_free (m_data);
|
||||
cleanup:
|
||||
asn1_delete_structure (&spk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* RFC 5280:
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING }
|
||||
*
|
||||
* AlgorithmIdentifiers come from RFC 3279, we are not strictly compilant as we
|
||||
* only support RSA Encryption.
|
||||
*/
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_x509_read_subject_public_key (asn1_node asn, VasEBoot_x509_cert_t *results)
|
||||
{
|
||||
VasEBoot_int32_t result;
|
||||
VasEBoot_err_t err;
|
||||
const char *algo_name = "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm";
|
||||
const char *params_name = "tbsCertificate.subjectPublicKeyInfo.algorithm.parameters";
|
||||
const char *pk_name = "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey";
|
||||
char algo_oid[VAS_EBOOT_MAX_OID_LEN];
|
||||
VasEBoot_int32_t algo_size = sizeof (algo_oid);
|
||||
char params_value[2];
|
||||
VasEBoot_int32_t params_size = sizeof (params_value);
|
||||
VasEBoot_uint8_t *key_data = NULL;
|
||||
VasEBoot_int32_t key_size = 0;
|
||||
VasEBoot_uint32_t key_type;
|
||||
|
||||
/* Algorithm: see notes for rsaEncryption_oid. */
|
||||
result = asn1_read_value (asn, algo_name, algo_oid, &algo_size);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading x509 public key algorithm: %s",
|
||||
asn1_strerror (result));
|
||||
|
||||
if (VasEBoot_strncmp (algo_oid, rsaEncryption_oid, sizeof (rsaEncryption_oid)) != 0)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unsupported x509 public key algorithm: %s", algo_oid);
|
||||
|
||||
/*
|
||||
* RFC 3279 2.3.1 : The rsaEncryption OID is intended to be used in the
|
||||
* algorithm field of a value of type AlgorithmIdentifier. The parameters
|
||||
* field MUST have ASN.1 type NULL for this algorithm identifier.
|
||||
*/
|
||||
result = asn1_read_value (asn, params_name, params_value, ¶ms_size);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading x509 public key parameters: %s",
|
||||
asn1_strerror (result));
|
||||
|
||||
if (params_value[0] != ASN1_TAG_NULL)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"invalid x509 public key parameters: expected NULL");
|
||||
|
||||
/*
|
||||
* RFC 3279 2.3.1: The DER encoded RSAPublicKey is the value of the BIT
|
||||
* STRING subjectPublicKey.
|
||||
*/
|
||||
result = asn1_read_value_type (asn, pk_name, NULL, &key_size, &key_type);
|
||||
if (result != ASN1_MEM_ERROR)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading size of x509 public key: %s",
|
||||
asn1_strerror (result));
|
||||
if (key_type != ASN1_ETYPE_BIT_STRING)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "unexpected ASN.1 type when reading x509 public key: %x",
|
||||
key_type);
|
||||
|
||||
/* Length is in bits. */
|
||||
key_size = (key_size + 7) / 8;
|
||||
|
||||
key_data = VasEBoot_malloc (key_size);
|
||||
if (key_data == NULL)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY, "out of memory for x509 public key");
|
||||
|
||||
result = asn1_read_value (asn, pk_name, key_data, &key_size);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
VasEBoot_free (key_data);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading public key data");
|
||||
}
|
||||
|
||||
key_size = (key_size + 7) / 8;
|
||||
err = VasEBoot_parse_rsa_pubkey (key_data, key_size, results);
|
||||
VasEBoot_free (key_data);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Decode a string as defined in Appendix A. */
|
||||
static VasEBoot_err_t
|
||||
decode_string (char *der, VasEBoot_int32_t der_size, char **string, VasEBoot_size_t *string_size)
|
||||
{
|
||||
asn1_node strasn;
|
||||
VasEBoot_int32_t result;
|
||||
char *choice;
|
||||
VasEBoot_int32_t choice_size = 0;
|
||||
VasEBoot_int32_t tmp_size = 0;
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_NONE;
|
||||
|
||||
result = asn1_create_element (VasEBoot_gnutls_pkix_asn, "PKIX1.DirectoryString", &strasn);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not create ASN.1 structure for certificate: %s",
|
||||
asn1_strerror (result));
|
||||
|
||||
result = asn1_der_decoding2 (&strasn, der, &der_size, ASN1_DECODE_FLAG_STRICT_DER, asn1_error);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"could not parse DER for DirectoryString: %s", asn1_error);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
choice = VasEBoot_asn1_allocate_and_read (strasn, "", "DirectoryString choice", &choice_size);
|
||||
if (choice == NULL)
|
||||
{
|
||||
err = VasEBoot_errno;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (VasEBoot_strncmp ("utf8String", choice, choice_size) == 0)
|
||||
{
|
||||
result = asn1_read_value (strasn, "utf8String", NULL, &tmp_size);
|
||||
if (result != ASN1_MEM_ERROR)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading size of UTF-8 string: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup_choice;
|
||||
}
|
||||
}
|
||||
else if (VasEBoot_strncmp ("printableString", choice, choice_size) == 0)
|
||||
{
|
||||
result = asn1_read_value (strasn, "printableString", NULL, &tmp_size);
|
||||
if (result != ASN1_MEM_ERROR)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading size of printableString: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup_choice;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_NOT_IMPLEMENTED_YET,
|
||||
"only UTF-8 and printable DirectoryStrings are supported, got %s",
|
||||
choice);
|
||||
goto cleanup_choice;
|
||||
}
|
||||
|
||||
/* Read size does not include trailing NUL. */
|
||||
tmp_size++;
|
||||
|
||||
*string = VasEBoot_malloc (tmp_size);
|
||||
if (*string == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"cannot allocate memory for DirectoryString contents");
|
||||
goto cleanup_choice;
|
||||
}
|
||||
|
||||
result = asn1_read_value (strasn, choice, *string, &tmp_size);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading out %s in DirectoryString: %s",
|
||||
choice, asn1_strerror (result));
|
||||
VasEBoot_free (*string);
|
||||
*string = NULL;
|
||||
goto cleanup_choice;
|
||||
}
|
||||
|
||||
*string_size = tmp_size + 1;
|
||||
(*string)[tmp_size] = '\0';
|
||||
|
||||
cleanup_choice:
|
||||
VasEBoot_free (choice);
|
||||
cleanup:
|
||||
asn1_delete_structure (&strasn);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* TBSCertificate ::= SEQUENCE {
|
||||
* version [0] EXPLICIT Version DEFAULT v1,
|
||||
* ...
|
||||
*
|
||||
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
||||
*/
|
||||
static VasEBoot_err_t
|
||||
check_version (asn1_node certificate, VasEBoot_x509_cert_t *results)
|
||||
{
|
||||
VasEBoot_int32_t rc;
|
||||
const char *name = "tbsCertificate.version";
|
||||
VasEBoot_uint8_t version;
|
||||
VasEBoot_int32_t len = sizeof (version);
|
||||
|
||||
rc = asn1_read_value (certificate, name, &version, &len);
|
||||
|
||||
/* Require version 3. */
|
||||
if (rc != ASN1_SUCCESS || len != 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading certificate version");
|
||||
|
||||
if (version != 0x02)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"invalid x509 certificate version, expected v3 (0x02), got 0x%02x.",
|
||||
version);
|
||||
|
||||
results->version = version;
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
/* we extract only the CN and issuer. */
|
||||
static VasEBoot_err_t
|
||||
read_name (asn1_node asn, const char *name_path, char **name, VasEBoot_size_t *name_size)
|
||||
{
|
||||
VasEBoot_int32_t seq_components, set_components;
|
||||
VasEBoot_int32_t result;
|
||||
VasEBoot_int32_t i, j;
|
||||
char *top_path, *set_path, *type_path, *val_path;
|
||||
char type[VAS_EBOOT_MAX_OID_LEN];
|
||||
VasEBoot_int32_t type_len = sizeof (type);
|
||||
VasEBoot_int32_t string_size = 0;
|
||||
char *string_der;
|
||||
VasEBoot_err_t err;
|
||||
|
||||
*name = NULL;
|
||||
|
||||
top_path = VasEBoot_xasprintf ("%s.rdnSequence", name_path);
|
||||
if (top_path == NULL)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not allocate memory for %s name parsing path", name_path);
|
||||
|
||||
result = asn1_number_of_elements (asn, top_path, &seq_components);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error counting name components: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 1; i <= seq_components; i++)
|
||||
{
|
||||
set_path = VasEBoot_xasprintf ("%s.?%d", top_path, i);
|
||||
if (set_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not allocate memory for %s name set parsing path",
|
||||
name_path);
|
||||
goto cleanup_set;
|
||||
}
|
||||
/* This brings us, hopefully, to a set. */
|
||||
result = asn1_number_of_elements (asn, set_path, &set_components);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"error counting name sub-components components (element %d): %s",
|
||||
i, asn1_strerror (result));
|
||||
goto cleanup_set;
|
||||
}
|
||||
for (j = 1; j <= set_components; j++)
|
||||
{
|
||||
type_path = VasEBoot_xasprintf ("%s.?%d.?%d.type", top_path, i, j);
|
||||
if (type_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not allocate memory for %s name component type path",
|
||||
name_path);
|
||||
goto cleanup_set;
|
||||
}
|
||||
type_len = sizeof (type);
|
||||
result = asn1_read_value (asn, type_path, type, &type_len);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading %s name component type: %s",
|
||||
name_path, asn1_strerror (result));
|
||||
goto cleanup_type;
|
||||
}
|
||||
|
||||
if (VasEBoot_strncmp (type, commonName_oid, type_len) != 0)
|
||||
{
|
||||
VasEBoot_free (type_path);
|
||||
continue;
|
||||
}
|
||||
|
||||
val_path = VasEBoot_xasprintf ("%s.?%d.?%d.value", top_path, i, j);
|
||||
if (val_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not allocate memory for %s name component value path",
|
||||
name_path);
|
||||
goto cleanup_type;
|
||||
}
|
||||
|
||||
string_der = VasEBoot_asn1_allocate_and_read (asn, val_path, name_path, &string_size);
|
||||
if (string_der == NULL)
|
||||
{
|
||||
err = VasEBoot_errno;
|
||||
goto cleanup_val_path;
|
||||
}
|
||||
|
||||
err = decode_string (string_der, string_size, name, name_size);
|
||||
if (err)
|
||||
goto cleanup_string;
|
||||
|
||||
VasEBoot_free (string_der);
|
||||
VasEBoot_free (type_path);
|
||||
VasEBoot_free (val_path);
|
||||
break;
|
||||
}
|
||||
|
||||
VasEBoot_free (set_path);
|
||||
if (*name)
|
||||
break;
|
||||
}
|
||||
|
||||
VasEBoot_free (top_path);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
|
||||
cleanup_string:
|
||||
VasEBoot_free (string_der);
|
||||
cleanup_val_path:
|
||||
VasEBoot_free (val_path);
|
||||
cleanup_type:
|
||||
VasEBoot_free (type_path);
|
||||
cleanup_set:
|
||||
VasEBoot_free (set_path);
|
||||
cleanup:
|
||||
VasEBoot_free (top_path);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Verify the Key Usage extension. We require the Digital Signature usage. */
|
||||
static VasEBoot_err_t
|
||||
verify_key_usage (VasEBoot_uint8_t *value, VasEBoot_int32_t value_size)
|
||||
{
|
||||
asn1_node usageasn;
|
||||
VasEBoot_int32_t result;
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_NONE;
|
||||
VasEBoot_uint8_t usage = 0xff;
|
||||
VasEBoot_int32_t usage_size = sizeof (usage_size);
|
||||
|
||||
result = asn1_create_element (VasEBoot_gnutls_pkix_asn, "PKIX1.KeyUsage", &usageasn);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not create ASN.1 structure for key usage");
|
||||
|
||||
result = asn1_der_decoding2 (&usageasn, value, &value_size,
|
||||
ASN1_DECODE_FLAG_STRICT_DER, asn1_error);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"error parsing DER for Key Usage: %s", asn1_error);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = asn1_read_value (usageasn, "", &usage, &usage_size);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading Key Usage value: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(usage & digitalSignatureUsage))
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"key usage (0x%x) missing Digital Signature usage", usage);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
asn1_delete_structure (&usageasn);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* BasicConstraints ::= SEQUENCE {
|
||||
* cA BOOLEAN DEFAULT FALSE,
|
||||
* pathLenConstraint INTEGER (0..MAX) OPTIONAL }
|
||||
*/
|
||||
static VasEBoot_err_t
|
||||
verify_basic_constraints (VasEBoot_uint8_t *value, VasEBoot_int32_t value_size)
|
||||
{
|
||||
asn1_node basicasn;
|
||||
VasEBoot_int32_t result;
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_NONE;
|
||||
char cA[6]; /* FALSE or TRUE. */
|
||||
VasEBoot_int32_t cA_size = sizeof (cA);
|
||||
|
||||
result = asn1_create_element (VasEBoot_gnutls_pkix_asn, "PKIX1.BasicConstraints", &basicasn);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not create ASN.1 structure for Basic Constraints");
|
||||
|
||||
result = asn1_der_decoding2 (&basicasn, value, &value_size,
|
||||
ASN1_DECODE_FLAG_STRICT_DER, asn1_error);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"error parsing DER for Basic Constraints: %s", asn1_error);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = asn1_read_value (basicasn, "cA", cA, &cA_size);
|
||||
if (result == ASN1_ELEMENT_NOT_FOUND)
|
||||
{
|
||||
/* Not present, default is False, so this is OK. */
|
||||
err = VAS_EBOOT_ERR_NONE;
|
||||
goto cleanup;
|
||||
}
|
||||
else if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading Basic Constraints cA value: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* The certificate must not be a CA certificate. */
|
||||
if (VasEBoot_strncmp ("FALSE", cA, cA_size) != 0)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "unexpected CA value: %s", cA);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
asn1_delete_structure (&basicasn);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify the Extended Key Usage extension. We require the Code Signing usage.
|
||||
*
|
||||
* ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
|
||||
*
|
||||
* KeyPurposeId ::= OBJECT IDENTIFIER
|
||||
*/
|
||||
static VasEBoot_err_t
|
||||
verify_extended_key_usage (VasEBoot_uint8_t *value, VasEBoot_int32_t value_size)
|
||||
{
|
||||
asn1_node extendedasn;
|
||||
VasEBoot_int32_t result, count, i = 0;
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_NONE;
|
||||
char usage[VAS_EBOOT_MAX_OID_LEN], name[3];
|
||||
VasEBoot_int32_t usage_size = sizeof (usage);
|
||||
|
||||
result = asn1_create_element (VasEBoot_gnutls_pkix_asn, "PKIX1.ExtKeyUsageSyntax", &extendedasn);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not create ASN.1 structure for Extended Key Usage");
|
||||
|
||||
result = asn1_der_decoding2 (&extendedasn, value, &value_size,
|
||||
ASN1_DECODE_FLAG_STRICT_DER, asn1_error);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"error parsing DER for Extended Key Usage: %s", asn1_error);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* If EKUs are present, it checks the presents of Code Signing usage. */
|
||||
result = asn1_number_of_elements (extendedasn, "", &count);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error counting number of Extended Key Usages: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 1; i < count + 1; i++)
|
||||
{
|
||||
VasEBoot_memset (name, 0, sizeof (name));
|
||||
VasEBoot_snprintf (name, sizeof (name), "?%d", i);
|
||||
result = asn1_read_value (extendedasn, name, usage, &usage_size);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading Extended Key Usage: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (VasEBoot_strncmp (codeSigningUsage_oid, usage, usage_size) == 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "extended key usage missing Code Signing usage");
|
||||
|
||||
cleanup:
|
||||
asn1_delete_structure (&extendedasn);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||
*
|
||||
* Extension ::= SEQUENCE {
|
||||
* extnID OBJECT IDENTIFIER,
|
||||
* critical BOOLEAN DEFAULT FALSE,
|
||||
* extnValue OCTET STRING
|
||||
* -- contains the DER encoding of an ASN.1 value
|
||||
* -- corresponding to the extension type identified
|
||||
* -- by extnID
|
||||
* }
|
||||
*
|
||||
* A certificate must:
|
||||
* - contain the Digital Signature usage
|
||||
* - not be a CA
|
||||
* - contain no extended usages, or contain the Code Signing extended usage
|
||||
* - not contain any other critical extensions (RFC 5280 s 4.2)
|
||||
*/
|
||||
static VasEBoot_err_t
|
||||
verify_extensions (asn1_node cert)
|
||||
{
|
||||
VasEBoot_int32_t result;
|
||||
VasEBoot_int32_t ext, num_extensions = 0;
|
||||
VasEBoot_int32_t usage_present = 0, constraints_present = 0, extended_usage_present = 0;
|
||||
char *oid_path, *critical_path, *value_path;
|
||||
char extnID[VAS_EBOOT_MAX_OID_LEN];
|
||||
VasEBoot_int32_t extnID_size;
|
||||
VasEBoot_err_t err;
|
||||
char critical[6]; /* We get either "TRUE" or "FALSE". */
|
||||
VasEBoot_int32_t critical_size;
|
||||
VasEBoot_uint8_t *value;
|
||||
VasEBoot_int32_t value_size;
|
||||
|
||||
result = asn1_number_of_elements (cert, "tbsCertificate.extensions", &num_extensions);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error counting number of extensions: %s",
|
||||
asn1_strerror (result));
|
||||
|
||||
if (num_extensions < 2)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"insufficient number of extensions for certificate, need at least 2, got %d",
|
||||
num_extensions);
|
||||
|
||||
for (ext = 1; ext <= num_extensions; ext++)
|
||||
{
|
||||
oid_path = VasEBoot_xasprintf ("tbsCertificate.extensions.?%d.extnID", ext);
|
||||
if (oid_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error extension OID path is empty");
|
||||
return err;
|
||||
}
|
||||
|
||||
extnID_size = sizeof (extnID);
|
||||
result = asn1_read_value (cert, oid_path, extnID, &extnID_size);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading extension OID: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup_oid_path;
|
||||
}
|
||||
|
||||
critical_path = VasEBoot_xasprintf ("tbsCertificate.extensions.?%d.critical", ext);
|
||||
if (critical_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error critical path is empty");
|
||||
goto cleanup_oid_path;
|
||||
}
|
||||
|
||||
critical_size = sizeof (critical);
|
||||
result = asn1_read_value (cert, critical_path, critical, &critical_size);
|
||||
if (result == ASN1_ELEMENT_NOT_FOUND)
|
||||
critical[0] = '\0';
|
||||
else if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error reading extension criticality: %s",
|
||||
asn1_strerror (result));
|
||||
goto cleanup_critical_path;
|
||||
}
|
||||
|
||||
value_path = VasEBoot_xasprintf ("tbsCertificate.extensions.?%d.extnValue", ext);
|
||||
if (value_path == NULL)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "error extnValue path is empty");
|
||||
goto cleanup_critical_path;
|
||||
}
|
||||
|
||||
value = VasEBoot_asn1_allocate_and_read (cert, value_path,
|
||||
"certificate extension value", &value_size);
|
||||
if (value == NULL)
|
||||
{
|
||||
err = VasEBoot_errno;
|
||||
goto cleanup_value_path;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we must see if we recognise the OID. If we have an unrecognised
|
||||
* critical extension we MUST bail.
|
||||
*/
|
||||
if (VasEBoot_strncmp (keyUsage_oid, extnID, extnID_size) == 0)
|
||||
{
|
||||
err = verify_key_usage (value, value_size);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
goto cleanup_value;
|
||||
|
||||
usage_present++;
|
||||
}
|
||||
else if (VasEBoot_strncmp (basicConstraints_oid, extnID, extnID_size) == 0)
|
||||
{
|
||||
err = verify_basic_constraints (value, value_size);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
goto cleanup_value;
|
||||
|
||||
constraints_present++;
|
||||
}
|
||||
else if (VasEBoot_strncmp (extendedKeyUsage_oid, extnID, extnID_size) == 0)
|
||||
{
|
||||
err = verify_extended_key_usage (value, value_size);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
goto cleanup_value;
|
||||
|
||||
extended_usage_present++;
|
||||
}
|
||||
else if (VasEBoot_strncmp ("TRUE", critical, critical_size) == 0)
|
||||
{
|
||||
/*
|
||||
* Per the RFC, we must not process a certificate with a critical
|
||||
* extension we do not understand.
|
||||
*/
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"unhandled critical x509 extension with OID %s", extnID);
|
||||
goto cleanup_value;
|
||||
}
|
||||
|
||||
VasEBoot_free (value);
|
||||
VasEBoot_free (value_path);
|
||||
VasEBoot_free (critical_path);
|
||||
VasEBoot_free (oid_path);
|
||||
}
|
||||
|
||||
if (usage_present != 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"unexpected number of Key Usage extensions - expected 1, got %d",
|
||||
usage_present);
|
||||
|
||||
if (constraints_present != 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"unexpected number of basic constraints extensions - expected 1, got %d",
|
||||
constraints_present);
|
||||
|
||||
if (extended_usage_present > 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"unexpected number of Extended Key Usage extensions - expected 0 or 1, got %d",
|
||||
extended_usage_present);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
|
||||
cleanup_value:
|
||||
VasEBoot_free (value);
|
||||
cleanup_value_path:
|
||||
VasEBoot_free (value_path);
|
||||
cleanup_critical_path:
|
||||
VasEBoot_free (critical_path);
|
||||
cleanup_oid_path:
|
||||
VasEBoot_free (oid_path);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
add_cert_fingerprint (const void *data, const VasEBoot_size_t data_size,
|
||||
VasEBoot_x509_cert_t *const cert)
|
||||
{
|
||||
/* Add SHA256 hash of certificate. */
|
||||
VasEBoot_crypto_hash ((gcry_md_spec_t *) &_gcry_digest_spec_sha256,
|
||||
&cert->fingerprint[VAS_EBOOT_FINGERPRINT_SHA256], data, data_size);
|
||||
/* Add SHA384 hash of certificate. */
|
||||
VasEBoot_crypto_hash ((gcry_md_spec_t *) &_gcry_digest_spec_sha384,
|
||||
&cert->fingerprint[VAS_EBOOT_FINGERPRINT_SHA384], data, data_size);
|
||||
/* Add SHA512 hash of certificate. */
|
||||
VasEBoot_crypto_hash ((gcry_md_spec_t *) &_gcry_digest_spec_sha512,
|
||||
&cert->fingerprint[VAS_EBOOT_FINGERPRINT_SHA512], data, data_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a certificate whose DER-encoded form is in @data, of size @data_size.
|
||||
* Return the results in @results, which must point to an allocated x509
|
||||
* certificate.
|
||||
*/
|
||||
VasEBoot_err_t
|
||||
VasEBoot_x509_cert_parse (const void *data, VasEBoot_size_t data_size, VasEBoot_x509_cert_t *results)
|
||||
{
|
||||
VasEBoot_int32_t result = 0;
|
||||
asn1_node cert;
|
||||
VasEBoot_err_t err;
|
||||
VasEBoot_int32_t tmp_size;
|
||||
VasEBoot_int32_t size = (VasEBoot_int32_t) data_size;
|
||||
|
||||
if (data_size > VAS_EBOOT_UINT_MAX)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_RANGE,
|
||||
"cannot parse a certificate where data size > VAS_EBOOT_UINT_MAX");
|
||||
|
||||
result = asn1_create_element (VasEBoot_gnutls_pkix_asn, "PKIX1.Certificate", &cert);
|
||||
if (result != ASN1_SUCCESS)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
"could not create ASN.1 structure for certificate: %s",
|
||||
asn1_strerror (result));
|
||||
|
||||
result = asn1_der_decoding2 (&cert, data, &size, ASN1_DECODE_FLAG_STRICT_DER, asn1_error);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
err = VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE,
|
||||
"could not parse DER for certificate: %s", asn1_error);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* TBSCertificate ::= SEQUENCE {
|
||||
* version [0] EXPLICIT Version DEFAULT v1
|
||||
*/
|
||||
err = check_version (cert, results);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
goto cleanup;
|
||||
|
||||
/*
|
||||
* serialNumber CertificateSerialNumber,
|
||||
*
|
||||
* CertificateSerialNumber ::= INTEGER
|
||||
*/
|
||||
results->serial = VasEBoot_asn1_allocate_and_read (cert, "tbsCertificate.serialNumber",
|
||||
"certificate serial number", &tmp_size);
|
||||
if (results->serial == NULL)
|
||||
{
|
||||
err = VasEBoot_errno;
|
||||
goto cleanup;
|
||||
}
|
||||
/*
|
||||
* It's safe to cast the signed int to an unsigned here, we know
|
||||
* length is non-negative.
|
||||
*/
|
||||
results->serial_len = tmp_size;
|
||||
|
||||
/*
|
||||
* signature AlgorithmIdentifier,
|
||||
*
|
||||
* We don't load the signature or issuer at the moment,
|
||||
* as we don't attempt x509 verification.
|
||||
*/
|
||||
|
||||
/*
|
||||
* validity Validity,
|
||||
*
|
||||
* Validity ::= SEQUENCE {
|
||||
* notBefore Time,
|
||||
* notAfter Time }
|
||||
*
|
||||
* We can't validate this reasonably, we have no true time source on several
|
||||
* platforms. For now we do not parse them.
|
||||
*/
|
||||
|
||||
/*
|
||||
* issuer Name,
|
||||
*
|
||||
* This is an X501 name, we parse out just the issuer.
|
||||
*/
|
||||
err = read_name (cert, "tbsCertificate.issuer", &results->issuer, &results->issuer_len);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
goto cleanup_serial;
|
||||
|
||||
/*
|
||||
* subject Name,
|
||||
*
|
||||
* This is an X501 name, we parse out just the CN.
|
||||
*/
|
||||
err = read_name (cert, "tbsCertificate.subject", &results->subject, &results->subject_len);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
goto cleanup_issuer;
|
||||
|
||||
/*
|
||||
* TBSCertificate ::= SEQUENCE {
|
||||
* ...
|
||||
* subjectPublicKeyInfo SubjectPublicKeyInfo,
|
||||
* ...
|
||||
*/
|
||||
err = VasEBoot_x509_read_subject_public_key (cert, results);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
goto cleanup_name;
|
||||
|
||||
/*
|
||||
* TBSCertificate ::= SEQUENCE {
|
||||
* ...
|
||||
* extensions [3] EXPLICIT Extensions OPTIONAL
|
||||
* -- If present, version MUST be v3
|
||||
* }
|
||||
*/
|
||||
err = verify_extensions (cert);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
goto cleanup_mpis;
|
||||
|
||||
/*
|
||||
* We do not read or check the signature on the certificate:
|
||||
* as discussed we do not try to validate the certificate but trust
|
||||
* it implictly.
|
||||
*/
|
||||
asn1_delete_structure (&cert);
|
||||
|
||||
/* Add the fingerprint of the certificate. */
|
||||
add_cert_fingerprint (data, data_size, results);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
|
||||
cleanup_mpis:
|
||||
_gcry_mpi_release (results->mpis[VAS_EBOOT_RSA_PK_MODULUS]);
|
||||
_gcry_mpi_release (results->mpis[VAS_EBOOT_RSA_PK_EXPONENT]);
|
||||
cleanup_name:
|
||||
VasEBoot_free (results->subject);
|
||||
cleanup_issuer:
|
||||
VasEBoot_free (results->issuer);
|
||||
cleanup_serial:
|
||||
VasEBoot_free (results->serial);
|
||||
cleanup:
|
||||
asn1_delete_structure (&cert);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release all the storage associated with the x509 certificate. If the caller
|
||||
* dynamically allocated the certificate, it must free it. The caller is also
|
||||
* responsible for maintenance of the linked list.
|
||||
*/
|
||||
void
|
||||
VasEBoot_x509_cert_release (VasEBoot_x509_cert_t *cert)
|
||||
{
|
||||
VasEBoot_free (cert->issuer);
|
||||
VasEBoot_free (cert->subject);
|
||||
VasEBoot_free (cert->serial);
|
||||
_gcry_mpi_release (cert->mpis[VAS_EBOOT_RSA_PK_MODULUS]);
|
||||
_gcry_mpi_release (cert->mpis[VAS_EBOOT_RSA_PK_EXPONENT]);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/arc/arc.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Helper for VasEBoot_cmd_lsdev. */
|
||||
static int
|
||||
VasEBoot_cmd_lsdev_iter (const char *name,
|
||||
const struct VasEBoot_arc_component *comp __attribute__ ((unused)),
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_printf ("%s\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_lsdev (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_arc_iterate_devs (VasEBoot_cmd_lsdev_iter, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(lsdev)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("lsdev", VasEBoot_cmd_lsdev, "",
|
||||
N_("List devices."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(lsdev)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Implementation of the Boot Loader Interface.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/charset.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
#include <VasEBoot/efi/disk.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/err.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/gpt_partition.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/partition.h>
|
||||
#include <VasEBoot/tpm.h>
|
||||
#include <VasEBoot/types.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define MODNAME "bli"
|
||||
|
||||
static const VasEBoot_guid_t bli_vendor_guid = VAS_EBOOT_EFI_VENDOR_BOOT_LOADER_INTERFACE_GUID;
|
||||
|
||||
static VasEBoot_err_t
|
||||
get_part_uuid (const char *device_name, char **part_uuid)
|
||||
{
|
||||
VasEBoot_device_t device;
|
||||
VasEBoot_err_t status = VAS_EBOOT_ERR_NONE;
|
||||
VasEBoot_disk_t disk = NULL;
|
||||
struct VasEBoot_gpt_partentry entry;
|
||||
|
||||
device = VasEBoot_device_open (device_name);
|
||||
if (device == NULL)
|
||||
return VasEBoot_error (VasEBoot_errno, N_("cannot open device: %s"), device_name);
|
||||
|
||||
if (device->disk == NULL)
|
||||
{
|
||||
VasEBoot_dprintf ("bli", "%s is not a disk device, partuuid skipped\n", device_name);
|
||||
*part_uuid = NULL;
|
||||
VasEBoot_device_close (device);
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
if (device->disk->partition == NULL)
|
||||
{
|
||||
VasEBoot_dprintf ("bli", "%s has no partition, partuuid skipped\n", device_name);
|
||||
*part_uuid = NULL;
|
||||
VasEBoot_device_close (device);
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
disk = VasEBoot_disk_open (device->disk->name);
|
||||
if (disk == NULL)
|
||||
{
|
||||
status = VasEBoot_error (VasEBoot_errno, N_("cannot open disk: %s"), device_name);
|
||||
VasEBoot_device_close (device);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (VasEBoot_strcmp (device->disk->partition->partmap->name, "gpt") != 0)
|
||||
{
|
||||
status = VasEBoot_error (VAS_EBOOT_ERR_BAD_PART_TABLE,
|
||||
N_("this is not a GPT partition table: %s"), device_name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (VasEBoot_disk_read (disk, device->disk->partition->offset,
|
||||
device->disk->partition->index, sizeof (entry), &entry) != VAS_EBOOT_ERR_NONE)
|
||||
{
|
||||
status = VasEBoot_error (VasEBoot_errno, N_("read error: %s"), device_name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*part_uuid = VasEBoot_xasprintf ("%pG", &entry.guid);
|
||||
if (*part_uuid == NULL)
|
||||
status = VasEBoot_errno;
|
||||
|
||||
fail:
|
||||
VasEBoot_disk_close (disk);
|
||||
VasEBoot_device_close (device);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
set_loader_device_part_uuid (void)
|
||||
{
|
||||
VasEBoot_efi_loaded_image_t *image;
|
||||
char *device_name;
|
||||
VasEBoot_err_t status = VAS_EBOOT_ERR_NONE;
|
||||
char *part_uuid = NULL;
|
||||
|
||||
image = VasEBoot_efi_get_loaded_image (VasEBoot_efi_image_handle);
|
||||
if (image == NULL)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_DEVICE, N_("unable to find boot device"));
|
||||
|
||||
device_name = VasEBoot_efidisk_get_device_name (image->device_handle);
|
||||
if (device_name == NULL)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_DEVICE, N_("unable to find boot device"));
|
||||
|
||||
status = get_part_uuid (device_name, &part_uuid);
|
||||
|
||||
if (status == VAS_EBOOT_ERR_NONE && part_uuid)
|
||||
status = VasEBoot_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid,
|
||||
VAS_EBOOT_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
VAS_EBOOT_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
else
|
||||
VasEBoot_error (status, N_("unable to determine partition UUID of boot device"));
|
||||
|
||||
VasEBoot_free (part_uuid);
|
||||
VasEBoot_free (device_name);
|
||||
return status;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
set_loader_active_pcr_banks (void)
|
||||
{
|
||||
VasEBoot_efi_uint32_t active_pcr_banks;
|
||||
char *active_pcr_banks_str;
|
||||
VasEBoot_err_t status;
|
||||
|
||||
active_pcr_banks = VasEBoot_tpm2_active_pcr_banks();
|
||||
active_pcr_banks_str = VasEBoot_xasprintf ("0x%08x", active_pcr_banks);
|
||||
if (active_pcr_banks_str == NULL)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY, N_("cannot allocate active PCR banks string"));
|
||||
|
||||
status = VasEBoot_efi_set_variable_to_string ("LoaderTpm2ActivePcrBanks",
|
||||
&bli_vendor_guid,
|
||||
active_pcr_banks_str,
|
||||
VAS_EBOOT_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
VAS_EBOOT_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
VasEBoot_free (active_pcr_banks_str);
|
||||
return status;
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_INIT (bli)
|
||||
{
|
||||
VasEBoot_efi_set_variable_to_string ("LoaderInfo", &bli_vendor_guid, PACKAGE_STRING,
|
||||
VAS_EBOOT_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
VAS_EBOOT_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
set_loader_device_part_uuid ();
|
||||
set_loader_active_pcr_banks ();
|
||||
/* No error here is critical, other than being logged */
|
||||
VasEBoot_print_error ();
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/* blocklist.c - print the block list of a file */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2006,2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/file.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/disk.h>
|
||||
#include <VasEBoot/partition.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Context for VasEBoot_cmd_blocklist. */
|
||||
struct blocklist_ctx
|
||||
{
|
||||
unsigned long start_sector;
|
||||
unsigned num_sectors;
|
||||
int num_entries;
|
||||
VasEBoot_disk_addr_t part_start;
|
||||
};
|
||||
|
||||
/* Helper for VasEBoot_cmd_blocklist. */
|
||||
static void
|
||||
print_blocklist (VasEBoot_disk_addr_t sector, unsigned num,
|
||||
unsigned offset, unsigned length, struct blocklist_ctx *ctx)
|
||||
{
|
||||
if (ctx->num_entries++)
|
||||
VasEBoot_printf (",");
|
||||
|
||||
VasEBoot_printf ("%llu", (unsigned long long) (sector - ctx->part_start));
|
||||
if (num > 0)
|
||||
VasEBoot_printf ("+%u", num);
|
||||
if (offset != 0 || length != 0)
|
||||
VasEBoot_printf ("[%u-%u]", offset, offset + length);
|
||||
}
|
||||
|
||||
/* Helper for VasEBoot_cmd_blocklist. */
|
||||
static VasEBoot_err_t
|
||||
read_blocklist (VasEBoot_disk_addr_t sector, unsigned offset, unsigned length,
|
||||
char *buf __attribute__ ((unused)), void *data)
|
||||
{
|
||||
struct blocklist_ctx *ctx = data;
|
||||
|
||||
if (ctx->num_sectors > 0)
|
||||
{
|
||||
if (ctx->start_sector + ctx->num_sectors == sector
|
||||
&& offset == 0 && length >= VAS_EBOOT_DISK_SECTOR_SIZE)
|
||||
{
|
||||
ctx->num_sectors += length >> VAS_EBOOT_DISK_SECTOR_BITS;
|
||||
sector += length >> VAS_EBOOT_DISK_SECTOR_BITS;
|
||||
length &= (VAS_EBOOT_DISK_SECTOR_SIZE - 1);
|
||||
}
|
||||
|
||||
if (!length)
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
print_blocklist (ctx->start_sector, ctx->num_sectors, 0, 0, ctx);
|
||||
ctx->num_sectors = 0;
|
||||
}
|
||||
|
||||
if (offset)
|
||||
{
|
||||
unsigned l = length + offset;
|
||||
l &= (VAS_EBOOT_DISK_SECTOR_SIZE - 1);
|
||||
l -= offset;
|
||||
print_blocklist (sector, 0, offset, l, ctx);
|
||||
length -= l;
|
||||
sector++;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if (!length)
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
|
||||
if (length & (VAS_EBOOT_DISK_SECTOR_SIZE - 1))
|
||||
{
|
||||
if (length >> VAS_EBOOT_DISK_SECTOR_BITS)
|
||||
{
|
||||
print_blocklist (sector, length >> VAS_EBOOT_DISK_SECTOR_BITS, 0, 0, ctx);
|
||||
sector += length >> VAS_EBOOT_DISK_SECTOR_BITS;
|
||||
}
|
||||
print_blocklist (sector, 0, 0, length & (VAS_EBOOT_DISK_SECTOR_SIZE - 1), ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->start_sector = sector;
|
||||
ctx->num_sectors = length >> VAS_EBOOT_DISK_SECTOR_BITS;
|
||||
}
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_blocklist (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
VasEBoot_file_t file;
|
||||
char buf[VAS_EBOOT_DISK_SECTOR_SIZE];
|
||||
struct blocklist_ctx ctx = {
|
||||
.start_sector = 0,
|
||||
.num_sectors = 0,
|
||||
.num_entries = 0,
|
||||
.part_start = 0
|
||||
};
|
||||
|
||||
if (argc < 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
file = VasEBoot_file_open (args[0], VAS_EBOOT_FILE_TYPE_PRINT_BLOCKLIST
|
||||
| VAS_EBOOT_FILE_TYPE_NO_DECOMPRESS);
|
||||
if (! file)
|
||||
return VasEBoot_errno;
|
||||
|
||||
if (! file->device->disk)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_DEVICE,
|
||||
"this command is available only for disk devices");
|
||||
|
||||
ctx.part_start = VasEBoot_partition_get_start (file->device->disk->partition);
|
||||
|
||||
file->read_hook = read_blocklist;
|
||||
file->read_hook_data = &ctx;
|
||||
|
||||
while (VasEBoot_file_read (file, buf, sizeof (buf)) > 0)
|
||||
;
|
||||
|
||||
if (ctx.num_sectors > 0)
|
||||
print_blocklist (ctx.start_sector, ctx.num_sectors, 0, 0, &ctx);
|
||||
|
||||
VasEBoot_file_close (file);
|
||||
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(blocklist)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("blocklist", VasEBoot_cmd_blocklist,
|
||||
N_("FILE"), N_("Print a block list."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(blocklist)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,245 @@
|
|||
/* boot.c - command to boot an operating system */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2003,2004,2005,2007,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/normal.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/loader.h>
|
||||
#include <VasEBoot/kernel.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_err_t (*VasEBoot_loader_boot_func) (void *context);
|
||||
static VasEBoot_err_t (*VasEBoot_loader_unload_func) (void *context);
|
||||
static void *VasEBoot_loader_context;
|
||||
static int VasEBoot_loader_flags;
|
||||
|
||||
struct VasEBoot_simple_loader_hooks
|
||||
{
|
||||
VasEBoot_err_t (*boot) (void);
|
||||
VasEBoot_err_t (*unload) (void);
|
||||
};
|
||||
|
||||
/* Don't heap allocate this to avoid making VasEBoot_loader_set() fallible. */
|
||||
static struct VasEBoot_simple_loader_hooks simple_loader_hooks;
|
||||
|
||||
struct VasEBoot_preboot
|
||||
{
|
||||
VasEBoot_err_t (*preboot_func) (int);
|
||||
VasEBoot_err_t (*preboot_rest_func) (void);
|
||||
VasEBoot_loader_preboot_hook_prio_t prio;
|
||||
struct VasEBoot_preboot *next;
|
||||
struct VasEBoot_preboot *prev;
|
||||
};
|
||||
|
||||
static int VasEBoot_loader_loaded;
|
||||
static struct VasEBoot_preboot *preboots_head = 0,
|
||||
*preboots_tail = 0;
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_simple_boot_hook (void *context)
|
||||
{
|
||||
struct VasEBoot_simple_loader_hooks *hooks;
|
||||
|
||||
hooks = (struct VasEBoot_simple_loader_hooks *) context;
|
||||
return hooks->boot ();
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_simple_unload_hook (void *context)
|
||||
{
|
||||
struct VasEBoot_simple_loader_hooks *hooks;
|
||||
VasEBoot_err_t ret;
|
||||
|
||||
hooks = (struct VasEBoot_simple_loader_hooks *) context;
|
||||
|
||||
ret = hooks->unload ();
|
||||
VasEBoot_memset (hooks, 0, sizeof (*hooks));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
VasEBoot_loader_is_loaded (void)
|
||||
{
|
||||
return VasEBoot_loader_loaded;
|
||||
}
|
||||
|
||||
/* Register a preboot hook. */
|
||||
struct VasEBoot_preboot *
|
||||
VasEBoot_loader_register_preboot_hook (VasEBoot_err_t (*preboot_func) (int flags),
|
||||
VasEBoot_err_t (*preboot_rest_func) (void),
|
||||
VasEBoot_loader_preboot_hook_prio_t prio)
|
||||
{
|
||||
struct VasEBoot_preboot *cur, *new_preboot;
|
||||
|
||||
if (! preboot_func && ! preboot_rest_func)
|
||||
return 0;
|
||||
|
||||
new_preboot = (struct VasEBoot_preboot *)
|
||||
VasEBoot_malloc (sizeof (struct VasEBoot_preboot));
|
||||
if (! new_preboot)
|
||||
return 0;
|
||||
|
||||
new_preboot->preboot_func = preboot_func;
|
||||
new_preboot->preboot_rest_func = preboot_rest_func;
|
||||
new_preboot->prio = prio;
|
||||
|
||||
for (cur = preboots_head; cur && cur->prio > prio; cur = cur->next);
|
||||
|
||||
if (cur)
|
||||
{
|
||||
new_preboot->next = cur;
|
||||
new_preboot->prev = cur->prev;
|
||||
cur->prev = new_preboot;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_preboot->next = 0;
|
||||
new_preboot->prev = preboots_tail;
|
||||
preboots_tail = new_preboot;
|
||||
}
|
||||
if (new_preboot->prev)
|
||||
new_preboot->prev->next = new_preboot;
|
||||
else
|
||||
preboots_head = new_preboot;
|
||||
|
||||
return new_preboot;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_loader_unregister_preboot_hook (struct VasEBoot_preboot *hnd)
|
||||
{
|
||||
struct VasEBoot_preboot *preb = hnd;
|
||||
|
||||
if (preb->next)
|
||||
preb->next->prev = preb->prev;
|
||||
else
|
||||
preboots_tail = preb->prev;
|
||||
if (preb->prev)
|
||||
preb->prev->next = preb->next;
|
||||
else
|
||||
preboots_head = preb->next;
|
||||
|
||||
VasEBoot_free (preb);
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_loader_set_ex (VasEBoot_err_t (*boot) (void *context),
|
||||
VasEBoot_err_t (*unload) (void *context),
|
||||
void *context,
|
||||
int flags)
|
||||
{
|
||||
if (VasEBoot_loader_loaded && VasEBoot_loader_unload_func)
|
||||
VasEBoot_loader_unload_func (VasEBoot_loader_context);
|
||||
|
||||
VasEBoot_loader_boot_func = boot;
|
||||
VasEBoot_loader_unload_func = unload;
|
||||
VasEBoot_loader_context = context;
|
||||
VasEBoot_loader_flags = flags;
|
||||
|
||||
VasEBoot_loader_loaded = 1;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_loader_set (VasEBoot_err_t (*boot) (void),
|
||||
VasEBoot_err_t (*unload) (void),
|
||||
int flags)
|
||||
{
|
||||
VasEBoot_loader_set_ex (VasEBoot_simple_boot_hook,
|
||||
VasEBoot_simple_unload_hook,
|
||||
&simple_loader_hooks,
|
||||
flags);
|
||||
|
||||
simple_loader_hooks.boot = boot;
|
||||
simple_loader_hooks.unload = unload;
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_loader_unset(void)
|
||||
{
|
||||
if (VasEBoot_loader_loaded && VasEBoot_loader_unload_func)
|
||||
VasEBoot_loader_unload_func (VasEBoot_loader_context);
|
||||
|
||||
VasEBoot_loader_boot_func = 0;
|
||||
VasEBoot_loader_unload_func = 0;
|
||||
VasEBoot_loader_context = 0;
|
||||
|
||||
VasEBoot_loader_loaded = 0;
|
||||
}
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_loader_boot (void)
|
||||
{
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_NONE;
|
||||
struct VasEBoot_preboot *cur;
|
||||
|
||||
if (! VasEBoot_loader_loaded)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_NO_KERNEL,
|
||||
N_("you need to load the kernel first"));
|
||||
|
||||
VasEBoot_machine_fini (VasEBoot_loader_flags);
|
||||
|
||||
for (cur = preboots_head; cur; cur = cur->next)
|
||||
{
|
||||
err = cur->preboot_func (VasEBoot_loader_flags);
|
||||
if (err)
|
||||
{
|
||||
for (cur = cur->prev; cur; cur = cur->prev)
|
||||
cur->preboot_rest_func ();
|
||||
return err;
|
||||
}
|
||||
}
|
||||
err = (VasEBoot_loader_boot_func) (VasEBoot_loader_context);
|
||||
|
||||
for (cur = preboots_tail; cur; cur = cur->prev)
|
||||
if (! err)
|
||||
err = cur->preboot_rest_func ();
|
||||
else
|
||||
cur->preboot_rest_func ();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* boot */
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_boot (struct VasEBoot_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char *argv[] __attribute__ ((unused)))
|
||||
{
|
||||
return VasEBoot_loader_boot ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static VasEBoot_command_t cmd_boot;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(boot)
|
||||
{
|
||||
cmd_boot =
|
||||
VasEBoot_register_command ("boot", VasEBoot_cmd_boot,
|
||||
0, N_("Boot an operating system."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(boot)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd_boot);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_boottime (struct VasEBoot_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char *argv[] __attribute__ ((unused)))
|
||||
{
|
||||
struct VasEBoot_boot_time *cur;
|
||||
VasEBoot_uint64_t last_time = 0, start_time = 0;
|
||||
if (!VasEBoot_boot_time_head)
|
||||
{
|
||||
VasEBoot_puts_ (N_("No boot time statistics is available\n"));
|
||||
return 0;
|
||||
}
|
||||
start_time = last_time = VasEBoot_boot_time_head->tp;
|
||||
for (cur = VasEBoot_boot_time_head; cur; cur = cur->next)
|
||||
{
|
||||
VasEBoot_uint32_t tmabs = cur->tp - start_time;
|
||||
VasEBoot_uint32_t tmrel = cur->tp - last_time;
|
||||
last_time = cur->tp;
|
||||
|
||||
VasEBoot_printf ("%3d.%03ds %2d.%03ds %s:%d %s\n",
|
||||
tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000, cur->file, cur->line,
|
||||
cur->msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd_boottime;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(boottime)
|
||||
{
|
||||
cmd_boottime =
|
||||
VasEBoot_register_command ("boottime", VasEBoot_cmd_boottime,
|
||||
0, N_("Show boot time statistics."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(boottime)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd_boottime);
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/* cacheinfo.c - disk cache statistics */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/disk.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_rescue_cmd_info (struct VasEBoot_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char *argv[] __attribute__ ((unused)))
|
||||
{
|
||||
unsigned long hits, misses;
|
||||
|
||||
VasEBoot_disk_cache_get_performance (&hits, &misses);
|
||||
if (hits + misses)
|
||||
{
|
||||
unsigned long ratio = hits * 10000 / (hits + misses);
|
||||
VasEBoot_printf ("(%lu.%lu%%)\n", ratio / 100, ratio % 100);
|
||||
VasEBoot_printf_ (N_("Disk cache statistics: hits = %lu (%lu.%02lu%%),"
|
||||
" misses = %lu\n"), ratio / 100, ratio % 100,
|
||||
hits, misses);
|
||||
}
|
||||
else
|
||||
VasEBoot_printf ("%s\n", _("No disk cache statistics available\n"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd_cacheinfo;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(cacheinfo)
|
||||
{
|
||||
cmd_cacheinfo =
|
||||
VasEBoot_register_command ("cacheinfo", VasEBoot_rescue_cmd_info,
|
||||
0, N_("Get disk cache info."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(cacheinfo)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd_cacheinfo);
|
||||
}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
/* cat.c - command to show the contents of a file */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/file.h>
|
||||
#include <VasEBoot/disk.h>
|
||||
#include <VasEBoot/term.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/charset.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct VasEBoot_arg_option options[] =
|
||||
{
|
||||
{"dos", -1, 0, N_("Accept DOS-style CR/NL line endings."), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_cat (VasEBoot_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct VasEBoot_arg_list *state = ctxt->state;
|
||||
int dos = 0;
|
||||
VasEBoot_file_t file;
|
||||
unsigned char buf[VAS_EBOOT_DISK_SECTOR_SIZE];
|
||||
VasEBoot_ssize_t size;
|
||||
int key = VAS_EBOOT_TERM_NO_KEY;
|
||||
VasEBoot_uint32_t code = 0;
|
||||
int count = 0;
|
||||
unsigned char utbuf[VAS_EBOOT_MAX_UTF8_PER_CODEPOINT + 1];
|
||||
int utcount = 0;
|
||||
int is_0d = 0;
|
||||
int j;
|
||||
|
||||
if (state[0].set)
|
||||
dos = 1;
|
||||
|
||||
if (argc != 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
file = VasEBoot_file_open (args[0], VAS_EBOOT_FILE_TYPE_CAT);
|
||||
if (! file)
|
||||
return VasEBoot_errno;
|
||||
|
||||
while ((size = VasEBoot_file_read (file, buf, sizeof (buf))) > 0
|
||||
&& key != VAS_EBOOT_TERM_ESC)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
utbuf[utcount++] = buf[i];
|
||||
|
||||
if (is_0d && buf[i] != '\n')
|
||||
{
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_HIGHLIGHT);
|
||||
VasEBoot_printf ("<%x>", (int) '\r');
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_STANDARD);
|
||||
}
|
||||
|
||||
is_0d = 0;
|
||||
|
||||
if (!VasEBoot_utf8_process (buf[i], &code, &count))
|
||||
{
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_HIGHLIGHT);
|
||||
for (j = 0; j < utcount - 1; j++)
|
||||
VasEBoot_printf ("<%x>", (unsigned int) utbuf[j]);
|
||||
code = 0;
|
||||
count = 0;
|
||||
if (utcount == 1 || !VasEBoot_utf8_process (buf[i], &code, &count))
|
||||
{
|
||||
VasEBoot_printf ("<%x>", (unsigned int) buf[i]);
|
||||
code = 0;
|
||||
count = 0;
|
||||
utcount = 0;
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_STANDARD);
|
||||
continue;
|
||||
}
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_STANDARD);
|
||||
utcount = 1;
|
||||
}
|
||||
if (count)
|
||||
continue;
|
||||
|
||||
if ((code >= 0xa1 || VasEBoot_isprint (code)
|
||||
|| VasEBoot_isspace (code)) && code != '\r')
|
||||
{
|
||||
VasEBoot_printf ("%C", code);
|
||||
count = 0;
|
||||
code = 0;
|
||||
utcount = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dos && code == '\r')
|
||||
{
|
||||
is_0d = 1;
|
||||
count = 0;
|
||||
code = 0;
|
||||
utcount = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_HIGHLIGHT);
|
||||
for (j = 0; j < utcount; j++)
|
||||
VasEBoot_printf ("<%x>", (unsigned int) utbuf[j]);
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_STANDARD);
|
||||
count = 0;
|
||||
code = 0;
|
||||
utcount = 0;
|
||||
}
|
||||
|
||||
do
|
||||
key = VasEBoot_getkey_noblock ();
|
||||
while (key != VAS_EBOOT_TERM_ESC && key != VAS_EBOOT_TERM_NO_KEY);
|
||||
}
|
||||
|
||||
if (is_0d)
|
||||
{
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_HIGHLIGHT);
|
||||
VasEBoot_printf ("<%x>", (unsigned int) '\r');
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_STANDARD);
|
||||
}
|
||||
|
||||
if (utcount)
|
||||
{
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_HIGHLIGHT);
|
||||
for (j = 0; j < utcount; j++)
|
||||
VasEBoot_printf ("<%x>", (unsigned int) utbuf[j]);
|
||||
VasEBoot_setcolorstate (VAS_EBOOT_TERM_COLOR_STANDARD);
|
||||
}
|
||||
|
||||
VasEBoot_xputs ("\n");
|
||||
VasEBoot_refresh ();
|
||||
VasEBoot_file_close (file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(cat)
|
||||
{
|
||||
cmd = VasEBoot_register_extcmd ("cat", VasEBoot_cmd_cat, 0,
|
||||
N_("FILE"), N_("Show the contents of a file."),
|
||||
options);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(cat)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/* cmd.c - command to cmp an operating system */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2005,2006,2007,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/file.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define BUFFER_SIZE 512
|
||||
|
||||
static const struct VasEBoot_arg_option options[] =
|
||||
{
|
||||
{0, 'v', 0, N_("Enable verbose output"), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_cmp (VasEBoot_extcmd_context_t ctxt,
|
||||
int argc, char **args)
|
||||
{
|
||||
VasEBoot_ssize_t rd1, rd2;
|
||||
VasEBoot_off_t pos;
|
||||
VasEBoot_file_t file1 = 0;
|
||||
VasEBoot_file_t file2 = 0;
|
||||
char *buf1 = 0;
|
||||
char *buf2 = 0;
|
||||
VasEBoot_err_t err = VAS_EBOOT_ERR_TEST_FAILURE;
|
||||
|
||||
if (argc != 2)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("two arguments expected"));
|
||||
|
||||
if (ctxt->state[0].set)
|
||||
VasEBoot_printf_ (N_("Compare file `%s' with `%s':\n"), args[0], args[1]);
|
||||
|
||||
file1 = VasEBoot_file_open (args[0], VAS_EBOOT_FILE_TYPE_CMP);
|
||||
file2 = VasEBoot_file_open (args[1], VAS_EBOOT_FILE_TYPE_CMP);
|
||||
if (! file1 || ! file2)
|
||||
goto cleanup;
|
||||
|
||||
if (ctxt->state[0].set && (VasEBoot_file_size (file1) != VasEBoot_file_size (file2)))
|
||||
VasEBoot_printf_ (N_("Files differ in size: %llu [%s], %llu [%s]\n"),
|
||||
(unsigned long long) VasEBoot_file_size (file1), args[0],
|
||||
(unsigned long long) VasEBoot_file_size (file2), args[1]);
|
||||
else
|
||||
{
|
||||
pos = 0;
|
||||
|
||||
buf1 = VasEBoot_malloc (BUFFER_SIZE);
|
||||
buf2 = VasEBoot_malloc (BUFFER_SIZE);
|
||||
|
||||
if (! buf1 || ! buf2)
|
||||
goto cleanup;
|
||||
|
||||
do
|
||||
{
|
||||
int i;
|
||||
|
||||
rd1 = VasEBoot_file_read (file1, buf1, BUFFER_SIZE);
|
||||
rd2 = VasEBoot_file_read (file2, buf2, BUFFER_SIZE);
|
||||
|
||||
if (rd1 != rd2)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < rd2; i++)
|
||||
{
|
||||
if (buf1[i] != buf2[i])
|
||||
{
|
||||
if (ctxt->state[0].set)
|
||||
VasEBoot_printf_ (N_("Files differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n"),
|
||||
(unsigned long long) (i + pos), buf1[i],
|
||||
args[0], buf2[i], args[1]);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
pos += BUFFER_SIZE;
|
||||
|
||||
}
|
||||
while (rd2);
|
||||
|
||||
/* TRANSLATORS: it's always exactly 2 files. */
|
||||
if (ctxt->state[0].set)
|
||||
VasEBoot_printf_ (N_("The files are identical.\n"));
|
||||
err = VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
VasEBoot_free (buf1);
|
||||
VasEBoot_free (buf2);
|
||||
if (file1)
|
||||
VasEBoot_file_close (file1);
|
||||
if (file2)
|
||||
VasEBoot_file_close (file2);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(cmp)
|
||||
{
|
||||
cmd = VasEBoot_register_extcmd ("cmp", VasEBoot_cmd_cmp, 0,
|
||||
N_("FILE1 FILE2"), N_("Compare two files."),
|
||||
options);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(cmp)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/* configfile.c - command to manually load config file */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2006,2007,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/term.h>
|
||||
#include <VasEBoot/env.h>
|
||||
#include <VasEBoot/normal.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_source (VasEBoot_command_t cmd, int argc, char **args)
|
||||
{
|
||||
int new_env, extractor;
|
||||
|
||||
if (argc != 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
extractor = (cmd->name[0] == 'e');
|
||||
new_env = (cmd->name[extractor ? sizeof ("extract_entries_") - 1 : 0] == 'c');
|
||||
|
||||
if (new_env)
|
||||
VasEBoot_cls ();
|
||||
|
||||
if (new_env && !extractor)
|
||||
VasEBoot_env_context_open ();
|
||||
if (extractor)
|
||||
VasEBoot_env_extractor_open (!new_env);
|
||||
|
||||
VasEBoot_normal_execute (args[0], 1, ! new_env);
|
||||
|
||||
if (new_env && !extractor)
|
||||
VasEBoot_env_context_close ();
|
||||
if (extractor)
|
||||
VasEBoot_env_extractor_close (!new_env);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd_configfile, cmd_source, cmd_dot;
|
||||
static VasEBoot_command_t cmd_extractor_source, cmd_extractor_configfile;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(configfile)
|
||||
{
|
||||
cmd_configfile =
|
||||
VasEBoot_register_command ("configfile", VasEBoot_cmd_source,
|
||||
N_("FILE"), N_("Load another config file."));
|
||||
cmd_source =
|
||||
VasEBoot_register_command ("source", VasEBoot_cmd_source,
|
||||
N_("FILE"),
|
||||
N_("Load another config file without changing context.")
|
||||
);
|
||||
|
||||
cmd_extractor_source =
|
||||
VasEBoot_register_command ("extract_entries_source", VasEBoot_cmd_source,
|
||||
N_("FILE"),
|
||||
N_("Load another config file without changing context but take only menu entries.")
|
||||
);
|
||||
|
||||
cmd_extractor_configfile =
|
||||
VasEBoot_register_command ("extract_entries_configfile", VasEBoot_cmd_source,
|
||||
N_("FILE"),
|
||||
N_("Load another config file but take only menu entries.")
|
||||
);
|
||||
|
||||
cmd_dot =
|
||||
VasEBoot_register_command (".", VasEBoot_cmd_source,
|
||||
N_("FILE"),
|
||||
N_("Load another config file without changing context.")
|
||||
);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(configfile)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd_configfile);
|
||||
VasEBoot_unregister_command (cmd_source);
|
||||
VasEBoot_unregister_command (cmd_extractor_configfile);
|
||||
VasEBoot_unregister_command (cmd_extractor_source);
|
||||
VasEBoot_unregister_command (cmd_dot);
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/* date.c - command to display/set current datetime. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/err.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/datetime.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define VAS_EBOOT_DATETIME_SET_YEAR 1
|
||||
#define VAS_EBOOT_DATETIME_SET_MONTH 2
|
||||
#define VAS_EBOOT_DATETIME_SET_DAY 4
|
||||
#define VAS_EBOOT_DATETIME_SET_HOUR 8
|
||||
#define VAS_EBOOT_DATETIME_SET_MINUTE 16
|
||||
#define VAS_EBOOT_DATETIME_SET_SECOND 32
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_date (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct VasEBoot_datetime datetime;
|
||||
int limit[6][2] = {{1980, 2079}, {1, 12}, {1, 31}, {0, 23}, {0, 59}, {0, 59}};
|
||||
int value[6], mask;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
if (VasEBoot_get_datetime (&datetime))
|
||||
return VasEBoot_errno;
|
||||
|
||||
VasEBoot_printf ("%d-%02d-%02d %02d:%02d:%02d %s\n",
|
||||
datetime.year, datetime.month, datetime.day,
|
||||
datetime.hour, datetime.minute, datetime.second,
|
||||
VasEBoot_get_weekday_name (&datetime));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VasEBoot_memset (&value, 0, sizeof (value));
|
||||
mask = 0;
|
||||
|
||||
for (; argc; argc--, args++)
|
||||
{
|
||||
const char *p;
|
||||
char c;
|
||||
int m1, ofs, n, cur_mask;
|
||||
|
||||
p = args[0];
|
||||
m1 = VasEBoot_strtoul (p, &p, 10);
|
||||
|
||||
c = *p;
|
||||
if (c == '-')
|
||||
ofs = 0;
|
||||
else if (c == ':')
|
||||
ofs = 3;
|
||||
else
|
||||
goto fail;
|
||||
|
||||
value[ofs] = m1;
|
||||
cur_mask = (1 << ofs);
|
||||
mask &= ~(cur_mask * (1 + 2 + 4));
|
||||
|
||||
for (n = 1; (n < 3) && (*p); n++)
|
||||
{
|
||||
if (*p != c)
|
||||
goto fail;
|
||||
|
||||
value[ofs + n] = VasEBoot_strtoul (p + 1, &p, 10);
|
||||
cur_mask |= (1 << (ofs + n));
|
||||
}
|
||||
|
||||
if (*p)
|
||||
goto fail;
|
||||
|
||||
if ((ofs == 0) && (n == 2))
|
||||
{
|
||||
value[ofs + 2] = value[ofs + 1];
|
||||
value[ofs + 1] = value[ofs];
|
||||
ofs++;
|
||||
cur_mask <<= 1;
|
||||
}
|
||||
|
||||
for (; n; n--, ofs++)
|
||||
if ((value [ofs] < limit[ofs][0]) ||
|
||||
(value [ofs] > limit[ofs][1]))
|
||||
goto fail;
|
||||
|
||||
mask |= cur_mask;
|
||||
}
|
||||
|
||||
if (VasEBoot_get_datetime (&datetime))
|
||||
return VasEBoot_errno;
|
||||
|
||||
if (mask & VAS_EBOOT_DATETIME_SET_YEAR)
|
||||
datetime.year = value[0];
|
||||
|
||||
if (mask & VAS_EBOOT_DATETIME_SET_MONTH)
|
||||
datetime.month = value[1];
|
||||
|
||||
if (mask & VAS_EBOOT_DATETIME_SET_DAY)
|
||||
datetime.day = value[2];
|
||||
|
||||
if (mask & VAS_EBOOT_DATETIME_SET_HOUR)
|
||||
datetime.hour = value[3];
|
||||
|
||||
if (mask & VAS_EBOOT_DATETIME_SET_MINUTE)
|
||||
datetime.minute = value[4];
|
||||
|
||||
if (mask & VAS_EBOOT_DATETIME_SET_SECOND)
|
||||
datetime.second = value[5];
|
||||
|
||||
return VasEBoot_set_datetime (&datetime);
|
||||
|
||||
fail:
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "invalid datetime");
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(date)
|
||||
{
|
||||
cmd =
|
||||
VasEBoot_register_command ("date", VasEBoot_cmd_date,
|
||||
N_("[[year-]month-day] [hour:minute[:second]]"),
|
||||
N_("Display/set current datetime."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(date)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/* echo.c - Command to display a line of text */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2006,2007,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/term.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct VasEBoot_arg_option options[] =
|
||||
{
|
||||
{0, 'n', 0, N_("Do not output the trailing newline."), 0, 0},
|
||||
{0, 'e', 0, N_("Enable interpretation of backslash escapes."), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_echo (VasEBoot_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct VasEBoot_arg_list *state = ctxt->state;
|
||||
int newline = 1;
|
||||
int i;
|
||||
|
||||
/* Check if `-n' was used. */
|
||||
if (state[0].set)
|
||||
newline = 0;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
char *arg = *args;
|
||||
/* Unescaping results in a string no longer than the original. */
|
||||
char *unescaped = VasEBoot_malloc (VasEBoot_strlen (arg) + 1);
|
||||
char *p = unescaped;
|
||||
args++;
|
||||
|
||||
if (!unescaped)
|
||||
return VasEBoot_errno;
|
||||
|
||||
while (*arg)
|
||||
{
|
||||
/* In case `-e' is used, parse backslashes. */
|
||||
if (*arg == '\\' && state[1].set)
|
||||
{
|
||||
arg++;
|
||||
if (*arg == '\0')
|
||||
break;
|
||||
|
||||
switch (*arg)
|
||||
{
|
||||
case '\\':
|
||||
*p++ = '\\';
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
*p++ = '\a';
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
newline = 0;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
*p++ = '\f';
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
*p++ = '\n';
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
*p++ = '\r';
|
||||
break;
|
||||
|
||||
case 't':
|
||||
*p++ = '\t';
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
*p++ = '\v';
|
||||
break;
|
||||
}
|
||||
arg++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* This was not an escaped character, or escaping is not
|
||||
enabled. */
|
||||
*p++ = *arg;
|
||||
arg++;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
VasEBoot_xputs (unescaped);
|
||||
VasEBoot_free (unescaped);
|
||||
|
||||
/* If another argument follows, insert a space. */
|
||||
if (i != argc - 1)
|
||||
VasEBoot_printf (" " );
|
||||
}
|
||||
|
||||
if (newline)
|
||||
VasEBoot_printf ("\n");
|
||||
|
||||
VasEBoot_refresh ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(echo)
|
||||
{
|
||||
cmd = VasEBoot_register_extcmd ("echo", VasEBoot_cmd_echo,
|
||||
VAS_EBOOT_COMMAND_ACCEPT_DASH
|
||||
| VAS_EBOOT_COMMAND_OPTIONS_AT_START,
|
||||
N_("[-e|-n] STRING"), N_("Display a line of text."),
|
||||
options);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(echo)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/* fwsetup.c - Reboot into firmware setup menu. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_efi_boolean_t efifwsetup_is_supported (void);
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_fwsetup (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_efi_uint64_t *old_os_indications;
|
||||
VasEBoot_efi_uint64_t os_indications = VAS_EBOOT_EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
|
||||
VasEBoot_err_t status;
|
||||
VasEBoot_size_t oi_size;
|
||||
static VasEBoot_guid_t global = VAS_EBOOT_EFI_GLOBAL_VARIABLE_GUID;
|
||||
|
||||
if (argc >= 1 && VasEBoot_strcmp(args[0], "--is-supported") == 0)
|
||||
return !efifwsetup_is_supported ();
|
||||
|
||||
if (!efifwsetup_is_supported ())
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_INVALID_COMMAND,
|
||||
N_("reboot to firmware setup is not supported by the current firmware"));
|
||||
|
||||
VasEBoot_efi_get_variable ("OsIndications", &global, &oi_size,
|
||||
(void **) &old_os_indications);
|
||||
|
||||
if (old_os_indications != NULL && oi_size == sizeof (os_indications))
|
||||
os_indications |= *old_os_indications;
|
||||
|
||||
VasEBoot_free (old_os_indications);
|
||||
|
||||
status = VasEBoot_efi_set_variable ("OsIndications", &global, &os_indications,
|
||||
sizeof (os_indications));
|
||||
if (status != VAS_EBOOT_ERR_NONE)
|
||||
return status;
|
||||
|
||||
VasEBoot_reboot ();
|
||||
|
||||
return VAS_EBOOT_ERR_BUG;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd = NULL;
|
||||
|
||||
static VasEBoot_efi_boolean_t
|
||||
efifwsetup_is_supported (void)
|
||||
{
|
||||
VasEBoot_efi_uint64_t *os_indications_supported = NULL;
|
||||
VasEBoot_size_t oi_size = 0;
|
||||
static VasEBoot_guid_t global = VAS_EBOOT_EFI_GLOBAL_VARIABLE_GUID;
|
||||
VasEBoot_efi_boolean_t ret = 0;
|
||||
|
||||
VasEBoot_efi_get_variable ("OsIndicationsSupported", &global, &oi_size,
|
||||
(void **) &os_indications_supported);
|
||||
|
||||
if (!os_indications_supported)
|
||||
goto done;
|
||||
|
||||
if (*os_indications_supported & VAS_EBOOT_EFI_OS_INDICATIONS_BOOT_TO_FW_UI)
|
||||
ret = 1;
|
||||
|
||||
done:
|
||||
VasEBoot_free (os_indications_supported);
|
||||
return ret;
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_INIT (efifwsetup)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("fwsetup", VasEBoot_cmd_fwsetup, NULL,
|
||||
N_("Reboot into firmware setup menu."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI (efifwsetup)
|
||||
{
|
||||
if (cmd)
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2022 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Set/Get UEFI text output mode resolution.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_efi_set_mode (VasEBoot_efi_simple_text_output_interface_t *o,
|
||||
VasEBoot_efi_int32_t mode)
|
||||
{
|
||||
VasEBoot_efi_status_t status;
|
||||
|
||||
if (mode != o->mode->mode)
|
||||
{
|
||||
status = o->set_mode (o, mode);
|
||||
if (status == VAS_EBOOT_EFI_SUCCESS)
|
||||
;
|
||||
else if (status == VAS_EBOOT_EFI_DEVICE_ERROR)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_DEVICE,
|
||||
N_("device error: could not set requested mode"));
|
||||
else if (status == VAS_EBOOT_EFI_UNSUPPORTED)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_RANGE,
|
||||
N_("invalid mode: number not valid"));
|
||||
else
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FIRMWARE,
|
||||
N_("unexpected EFI error number: `%u'"),
|
||||
(unsigned) status);
|
||||
}
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_efitextmode (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
VasEBoot_efi_simple_text_output_interface_t *o = VasEBoot_efi_system_table->con_out;
|
||||
unsigned long mode;
|
||||
const char *p = NULL;
|
||||
VasEBoot_err_t err;
|
||||
VasEBoot_efi_uintn_t columns, rows;
|
||||
VasEBoot_efi_int32_t i;
|
||||
|
||||
if (o == NULL)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_DEVICE, N_("no UEFI output console interface"));
|
||||
|
||||
if (o->mode == NULL)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BUG, N_("no mode struct for UEFI output console"));
|
||||
|
||||
if (argc > 2)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("at most two arguments expected"));
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
VasEBoot_printf_ (N_("Available modes for console output device.\n"));
|
||||
|
||||
for (i = 0; i < o->mode->max_mode; i++)
|
||||
if (VAS_EBOOT_EFI_SUCCESS == o->query_mode (o, i, &columns, &rows))
|
||||
VasEBoot_printf_ (N_(" [%" PRIuVAS_EBOOT_EFI_UINT32_T "] Col %5"
|
||||
PRIuVAS_EBOOT_EFI_UINTN_T " Row %5" PRIuVAS_EBOOT_EFI_UINTN_T
|
||||
" %c\n"),
|
||||
i, columns, rows, (i == o->mode->mode) ? '*' : ' ');
|
||||
}
|
||||
else if (argc == 1)
|
||||
{
|
||||
if (VasEBoot_strcmp (args[0], "min") == 0)
|
||||
mode = 0;
|
||||
else if (VasEBoot_strcmp (args[0], "max") == 0)
|
||||
mode = o->mode->max_mode - 1;
|
||||
else
|
||||
{
|
||||
mode = VasEBoot_strtoul (args[0], &p, 0);
|
||||
|
||||
if (*args[0] == '\0' || *p != '\0')
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("non-numeric or invalid mode `%s'"), args[0]);
|
||||
}
|
||||
|
||||
if (mode < (unsigned long) o->mode->max_mode)
|
||||
{
|
||||
err = VasEBoot_efi_set_mode (o, (VasEBoot_efi_int32_t) mode);
|
||||
if (err != VAS_EBOOT_ERR_NONE)
|
||||
return err;
|
||||
}
|
||||
else
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("invalid mode: `%lu' is greater than maximum mode `%lu'"),
|
||||
mode, (unsigned long) o->mode->max_mode);
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
VasEBoot_efi_uintn_t u_columns, u_rows;
|
||||
|
||||
u_columns = (VasEBoot_efi_uintn_t) VasEBoot_strtoul (args[0], &p, 0);
|
||||
|
||||
if (*args[0] == '\0' || *p != '\0')
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("non-numeric or invalid columns number `%s'"), args[0]);
|
||||
|
||||
u_rows = (VasEBoot_efi_uintn_t) VasEBoot_strtoul (args[1], &p, 0);
|
||||
|
||||
if (*args[1] == '\0' || *p != '\0')
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("non-numeric or invalid rows number `%s'"), args[1]);
|
||||
|
||||
for (i = 0; i < o->mode->max_mode; i++)
|
||||
if (VAS_EBOOT_EFI_SUCCESS == o->query_mode (o, i, &columns, &rows))
|
||||
if (u_columns == columns && u_rows == rows)
|
||||
return VasEBoot_efi_set_mode (o, (VasEBoot_efi_int32_t) i);
|
||||
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
N_("no mode found with requested columns and rows"));
|
||||
}
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
VAS_EBOOT_MOD_INIT (efitextmode)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("efitextmode", VasEBoot_cmd_efitextmode,
|
||||
N_("[min | max | <mode_num> | <cols> <rows>]"),
|
||||
N_("Get or set EFI text mode."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI (efitextmode)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/* fixvideo.c - fix video problem in efi */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/file.h>
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static struct VasEBoot_video_patch
|
||||
{
|
||||
const char *name;
|
||||
VasEBoot_uint32_t pci_id;
|
||||
VasEBoot_uint32_t mmio_bar;
|
||||
VasEBoot_uint32_t mmio_reg;
|
||||
VasEBoot_uint32_t mmio_old;
|
||||
} video_patches[] =
|
||||
{
|
||||
{"Intel 945GM", 0x27a28086, 0, 0x71184, 0x1000000}, /* DSPBBASE */
|
||||
{"Intel 965GM", 0x2a028086, 0, 0x7119C, 0x1000000}, /* DSPBSURF */
|
||||
{0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static int
|
||||
scan_card (VasEBoot_pci_device_t dev, VasEBoot_pci_id_t pciid,
|
||||
void *data __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_pci_address_t addr;
|
||||
|
||||
addr = VasEBoot_pci_make_address (dev, VAS_EBOOT_PCI_REG_CLASS);
|
||||
if (VasEBoot_pci_read_byte (addr + 3) == 0x3)
|
||||
{
|
||||
struct VasEBoot_video_patch *p = video_patches;
|
||||
|
||||
while (p->name)
|
||||
{
|
||||
if (p->pci_id == pciid)
|
||||
{
|
||||
VasEBoot_addr_t base;
|
||||
|
||||
VasEBoot_dprintf ("fixvideo", "Found graphic card: %s\n", p->name);
|
||||
addr += 8 + p->mmio_bar * 4;
|
||||
base = VasEBoot_pci_read (addr);
|
||||
if ((! base) || (base & VAS_EBOOT_PCI_ADDR_SPACE_IO) ||
|
||||
(base & VAS_EBOOT_PCI_ADDR_MEM_PREFETCH))
|
||||
VasEBoot_dprintf ("fixvideo", "Invalid MMIO bar %d\n", p->mmio_bar);
|
||||
else
|
||||
{
|
||||
base &= VAS_EBOOT_PCI_ADDR_MEM_MASK;
|
||||
base += p->mmio_reg;
|
||||
|
||||
if (*((volatile VasEBoot_uint32_t *) base) != p->mmio_old)
|
||||
VasEBoot_dprintf ("fixvideo", "Old value doesn't match\n");
|
||||
else
|
||||
{
|
||||
*((volatile VasEBoot_uint32_t *) base) = 0;
|
||||
if (*((volatile VasEBoot_uint32_t *) base))
|
||||
VasEBoot_dprintf ("fixvideo", "Setting MMIO fails\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
VasEBoot_dprintf ("fixvideo", "Unknown graphic card: %x\n", pciid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_fixvideo (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char *argv[] __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_pci_iterate (scan_card, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd_fixvideo;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(fixvideo)
|
||||
{
|
||||
cmd_fixvideo = VasEBoot_register_command ("fix_video", VasEBoot_cmd_fixvideo,
|
||||
0, N_("Fix video problem."));
|
||||
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(fixvideo)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd_fixvideo);
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/* getenv.c - retrieve EFI variables. */
|
||||
/*
|
||||
* VasEBoot -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2014 CoreOS, Inc.
|
||||
*
|
||||
* VasEBoot 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.
|
||||
*
|
||||
* VasEBoot 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 VasEBoot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/env.h>
|
||||
#include <VasEBoot/err.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
|
||||
VasEBoot_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct VasEBoot_arg_option options_getenv[] = {
|
||||
{"var-name", 'e', 0,
|
||||
N_("Environment variable to query"),
|
||||
N_("VARNAME"), ARG_TYPE_STRING},
|
||||
{"var-guid", 'g', 0,
|
||||
N_("GUID of environment variable to query"),
|
||||
N_("GUID"), ARG_TYPE_STRING},
|
||||
{"binary", 'b', 0,
|
||||
N_("Read binary data and represent it as hex"),
|
||||
0, ARG_TYPE_NONE},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
enum options_getenv
|
||||
{
|
||||
GETENV_VAR_NAME,
|
||||
GETENV_VAR_GUID,
|
||||
GETENV_BINARY,
|
||||
};
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_getenv (VasEBoot_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct VasEBoot_arg_list *state = ctxt->state;
|
||||
char *envvar = NULL, *guid = NULL, *bindata = NULL, *data = NULL;
|
||||
VasEBoot_size_t datasize;
|
||||
VasEBoot_efi_guid_t efi_var_guid;
|
||||
VasEBoot_efi_boolean_t binary = state[GETENV_BINARY].set;
|
||||
unsigned int i;
|
||||
|
||||
if (!state[GETENV_VAR_NAME].set || !state[GETENV_VAR_GUID].set)
|
||||
{
|
||||
VasEBoot_error (VasEBoot_ERR_INVALID_COMMAND, N_("-e and -g are required"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
VasEBoot_error (VasEBoot_ERR_BAD_ARGUMENT, N_("unexpected arguments"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
envvar = state[GETENV_VAR_NAME].arg;
|
||||
guid = state[GETENV_VAR_GUID].arg;
|
||||
|
||||
if (VasEBoot_strlen(guid) != 36 ||
|
||||
guid[8] != '-' ||
|
||||
guid[13] != '-' ||
|
||||
guid[18] != '-' ||
|
||||
guid[23] != '-')
|
||||
{
|
||||
VasEBoot_error (VasEBoot_ERR_BAD_ARGUMENT, N_("invalid GUID"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Forgive me father for I have sinned */
|
||||
guid[8] = 0;
|
||||
efi_var_guid.data1 = VasEBoot_strtoul(guid, NULL, 16);
|
||||
guid[13] = 0;
|
||||
efi_var_guid.data2 = VasEBoot_strtoul(guid + 9, NULL, 16);
|
||||
guid[18] = 0;
|
||||
efi_var_guid.data3 = VasEBoot_strtoul(guid + 14, NULL, 16);
|
||||
efi_var_guid.data4[7] = VasEBoot_strtoul(guid + 34, NULL, 16);
|
||||
guid[34] = 0;
|
||||
efi_var_guid.data4[6] = VasEBoot_strtoul(guid + 32, NULL, 16);
|
||||
guid[32] = 0;
|
||||
efi_var_guid.data4[5] = VasEBoot_strtoul(guid + 30, NULL, 16);
|
||||
guid[30] = 0;
|
||||
efi_var_guid.data4[4] = VasEBoot_strtoul(guid + 28, NULL, 16);
|
||||
guid[28] = 0;
|
||||
efi_var_guid.data4[3] = VasEBoot_strtoul(guid + 26, NULL, 16);
|
||||
guid[26] = 0;
|
||||
efi_var_guid.data4[2] = VasEBoot_strtoul(guid + 24, NULL, 16);
|
||||
guid[23] = 0;
|
||||
efi_var_guid.data4[1] = VasEBoot_strtoul(guid + 21, NULL, 16);
|
||||
guid[21] = 0;
|
||||
efi_var_guid.data4[0] = VasEBoot_strtoul(guid + 19, NULL, 16);
|
||||
|
||||
data = VasEBoot_efi_get_variable(envvar, &efi_var_guid, &datasize);
|
||||
|
||||
if (!data || !datasize)
|
||||
{
|
||||
VasEBoot_error (VasEBoot_ERR_FILE_NOT_FOUND, N_("No such variable"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (binary)
|
||||
{
|
||||
bindata = VasEBoot_zalloc(datasize * 2 + 1);
|
||||
for (i=0; i<datasize; i++)
|
||||
VasEBoot_snprintf(bindata + i*2, 3, "%02x", data[i] & 0xff);
|
||||
|
||||
if (VasEBoot_env_set (args[0], bindata))
|
||||
goto done;
|
||||
}
|
||||
else if (VasEBoot_env_set (args[0], data))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
VasEBoot_errno = VasEBoot_ERR_NONE;
|
||||
|
||||
done:
|
||||
VasEBoot_free(bindata);
|
||||
VasEBoot_free(data);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd_getenv;
|
||||
|
||||
VasEBoot_MOD_INIT(getenv)
|
||||
{
|
||||
cmd_getenv = VasEBoot_register_extcmd ("getenv", VasEBoot_cmd_getenv, 0,
|
||||
N_("-e envvar -g guidenv setvar"),
|
||||
N_("Read a firmware environment variable"),
|
||||
options_getenv);
|
||||
}
|
||||
|
||||
VasEBoot_MOD_FINI(getenv)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd_getenv);
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
/* loadbios.c - command to load a bios dump */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/file.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/pci.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_guid_t acpi_guid = VAS_EBOOT_EFI_ACPI_TABLE_GUID;
|
||||
static VasEBoot_guid_t acpi2_guid = VAS_EBOOT_EFI_ACPI_20_TABLE_GUID;
|
||||
static VasEBoot_guid_t smbios_guid = VAS_EBOOT_EFI_SMBIOS_TABLE_GUID;
|
||||
|
||||
#define EBDA_SEG_ADDR 0x40e
|
||||
#define LOW_MEM_ADDR 0x413
|
||||
#define FAKE_EBDA_SEG 0x9fc0
|
||||
|
||||
#define BLANK_MEM 0xffffffff
|
||||
#define VBIOS_ADDR 0xc0000
|
||||
#define SBIOS_ADDR 0xf0000
|
||||
|
||||
static int
|
||||
enable_rom_area (void)
|
||||
{
|
||||
VasEBoot_pci_address_t addr;
|
||||
VasEBoot_uint32_t *rom_ptr;
|
||||
VasEBoot_pci_device_t dev = { .bus = 0, .device = 0, .function = 0};
|
||||
|
||||
rom_ptr = VasEBoot_absolute_pointer (VBIOS_ADDR);
|
||||
if (*rom_ptr != BLANK_MEM)
|
||||
{
|
||||
VasEBoot_puts_ (N_("ROM image is present."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: should be macroified. */
|
||||
addr = VasEBoot_pci_make_address (dev, 144);
|
||||
VasEBoot_pci_write_byte (addr++, 0x30);
|
||||
VasEBoot_pci_write_byte (addr++, 0x33);
|
||||
VasEBoot_pci_write_byte (addr++, 0x33);
|
||||
VasEBoot_pci_write_byte (addr++, 0x33);
|
||||
VasEBoot_pci_write_byte (addr++, 0x33);
|
||||
VasEBoot_pci_write_byte (addr++, 0x33);
|
||||
VasEBoot_pci_write_byte (addr++, 0x33);
|
||||
VasEBoot_pci_write_byte (addr, 0);
|
||||
|
||||
*rom_ptr = 0;
|
||||
if (*rom_ptr != 0)
|
||||
{
|
||||
VasEBoot_puts_ (N_("Can\'t enable ROM area."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
lock_rom_area (void)
|
||||
{
|
||||
VasEBoot_pci_address_t addr;
|
||||
VasEBoot_pci_device_t dev = { .bus = 0, .device = 0, .function = 0};
|
||||
|
||||
/* FIXME: should be macroified. */
|
||||
addr = VasEBoot_pci_make_address (dev, 144);
|
||||
VasEBoot_pci_write_byte (addr++, 0x10);
|
||||
VasEBoot_pci_write_byte (addr++, 0x11);
|
||||
VasEBoot_pci_write_byte (addr++, 0x11);
|
||||
VasEBoot_pci_write_byte (addr++, 0x11);
|
||||
VasEBoot_pci_write_byte (addr, 0x11);
|
||||
}
|
||||
|
||||
static void
|
||||
fake_bios_data (int use_rom)
|
||||
{
|
||||
void *acpi, *smbios;
|
||||
VasEBoot_uint16_t *ebda_seg_ptr, *low_mem_ptr;
|
||||
|
||||
ebda_seg_ptr = VasEBoot_absolute_pointer (EBDA_SEG_ADDR);
|
||||
low_mem_ptr = VasEBoot_absolute_pointer (LOW_MEM_ADDR);
|
||||
if ((*ebda_seg_ptr) || (*low_mem_ptr))
|
||||
return;
|
||||
|
||||
acpi = VasEBoot_efi_find_configuration_table (&acpi2_guid);
|
||||
VasEBoot_dprintf ("efi", "ACPI2: %p\n", acpi);
|
||||
if (!acpi) {
|
||||
acpi = VasEBoot_efi_find_configuration_table (&acpi_guid);
|
||||
VasEBoot_dprintf ("efi", "ACPI: %p\n", acpi);
|
||||
}
|
||||
|
||||
smbios = VasEBoot_efi_find_configuration_table (&smbios_guid);
|
||||
VasEBoot_dprintf ("efi", "SMBIOS: %p\n", smbios);
|
||||
|
||||
*ebda_seg_ptr = FAKE_EBDA_SEG;
|
||||
*low_mem_ptr = (FAKE_EBDA_SEG >> 6);
|
||||
|
||||
/* *((VasEBoot_uint16_t *) (FAKE_EBDA_SEG << 4)) = 640 - *low_mem_ptr; */
|
||||
*((VasEBoot_uint16_t *) (VasEBoot_absolute_pointer (FAKE_EBDA_SEG << 4))) = 640 - *low_mem_ptr;
|
||||
|
||||
if (acpi)
|
||||
VasEBoot_memcpy ((char *) ((FAKE_EBDA_SEG << 4) + 16), acpi, 1024 - 16);
|
||||
|
||||
if ((use_rom) && (smbios))
|
||||
VasEBoot_memcpy ((char *) SBIOS_ADDR, (char *) smbios + 16, 16);
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_fakebios (struct VasEBoot_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char *argv[] __attribute__ ((unused)))
|
||||
{
|
||||
if (enable_rom_area ())
|
||||
{
|
||||
fake_bios_data (1);
|
||||
lock_rom_area ();
|
||||
}
|
||||
else
|
||||
fake_bios_data (0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_loadbios (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
VasEBoot_file_t file;
|
||||
int size;
|
||||
|
||||
if (argc == 0)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
file = VasEBoot_file_open (argv[1], VAS_EBOOT_FILE_TYPE_VBE_DUMP);
|
||||
if (! file)
|
||||
return VasEBoot_errno;
|
||||
|
||||
if (file->size != 4)
|
||||
VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "invalid int10 dump size");
|
||||
else
|
||||
VasEBoot_file_read (file, (void *) 0x40, 4);
|
||||
|
||||
VasEBoot_file_close (file);
|
||||
if (VasEBoot_errno)
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
file = VasEBoot_file_open (argv[0], VAS_EBOOT_FILE_TYPE_VBE_DUMP);
|
||||
if (! file)
|
||||
return VasEBoot_errno;
|
||||
|
||||
size = file->size;
|
||||
if ((size < 0x10000) || (size > 0x40000))
|
||||
VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "invalid bios dump size");
|
||||
else if (enable_rom_area ())
|
||||
{
|
||||
VasEBoot_file_read (file, (void *) VBIOS_ADDR, size);
|
||||
fake_bios_data (size <= 0x40000);
|
||||
lock_rom_area ();
|
||||
}
|
||||
|
||||
VasEBoot_file_close (file);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd_fakebios, cmd_loadbios;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(loadbios)
|
||||
{
|
||||
cmd_fakebios = VasEBoot_register_command_lockdown ("fakebios", VasEBoot_cmd_fakebios,
|
||||
0, N_("Create BIOS-like structures for"
|
||||
" backward compatibility with"
|
||||
" existing OS."));
|
||||
|
||||
cmd_loadbios = VasEBoot_register_command_lockdown ("loadbios", VasEBoot_cmd_loadbios,
|
||||
N_("BIOS_DUMP [INT10_DUMP]"),
|
||||
N_("Load BIOS dump."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(loadbios)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd_fakebios);
|
||||
VasEBoot_unregister_command (cmd_loadbios);
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
#include <VasEBoot/efi/edid.h>
|
||||
#include <VasEBoot/efi/pci.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/efi/uga_draw.h>
|
||||
#include <VasEBoot/efi/graphics_output.h>
|
||||
#include <VasEBoot/efi/console_control.h>
|
||||
#include <VasEBoot/command.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static struct known_protocol
|
||||
{
|
||||
VasEBoot_guid_t guid;
|
||||
const char *name;
|
||||
} known_protocols[] =
|
||||
{
|
||||
{ VAS_EBOOT_EFI_DISK_IO_GUID, "disk" },
|
||||
{ VAS_EBOOT_EFI_BLOCK_IO_GUID, "block" },
|
||||
{ VAS_EBOOT_EFI_SERIAL_IO_GUID, "serial" },
|
||||
{ VAS_EBOOT_EFI_SIMPLE_NETWORK_GUID, "network" },
|
||||
{ VAS_EBOOT_EFI_PXE_GUID, "pxe" },
|
||||
{ VAS_EBOOT_EFI_DEVICE_PATH_GUID, "device path" },
|
||||
{ VAS_EBOOT_EFI_PCI_IO_GUID, "PCI" },
|
||||
{ VAS_EBOOT_EFI_PCI_ROOT_IO_GUID, "PCI root" },
|
||||
{ VAS_EBOOT_EFI_EDID_ACTIVE_GUID, "active EDID" },
|
||||
{ VAS_EBOOT_EFI_EDID_DISCOVERED_GUID, "discovered EDID" },
|
||||
{ VAS_EBOOT_EFI_EDID_OVERRIDE_GUID, "override EDID" },
|
||||
{ VAS_EBOOT_EFI_GOP_GUID, "GOP" },
|
||||
{ VAS_EBOOT_EFI_UGA_DRAW_GUID, "UGA draw" },
|
||||
{ VAS_EBOOT_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID, "simple text output" },
|
||||
{ VAS_EBOOT_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID, "simple text input" },
|
||||
{ VAS_EBOOT_EFI_SIMPLE_POINTER_PROTOCOL_GUID, "simple pointer" },
|
||||
{ VAS_EBOOT_EFI_CONSOLE_CONTROL_GUID, "console control" },
|
||||
{ VAS_EBOOT_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID, "absolute pointer" },
|
||||
{ VAS_EBOOT_EFI_DRIVER_BINDING_PROTOCOL_GUID, "EFI driver binding" },
|
||||
{ VAS_EBOOT_EFI_LOAD_FILE_PROTOCOL_GUID, "load file" },
|
||||
{ VAS_EBOOT_EFI_LOAD_FILE2_PROTOCOL_GUID, "load file2" },
|
||||
{ VAS_EBOOT_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "simple FS" },
|
||||
{ VAS_EBOOT_EFI_TAPE_IO_PROTOCOL_GUID, "tape I/O" },
|
||||
{ VAS_EBOOT_EFI_UNICODE_COLLATION_PROTOCOL_GUID, "unicode collation" },
|
||||
{ VAS_EBOOT_EFI_SCSI_IO_PROTOCOL_GUID, "SCSI I/O" },
|
||||
{ VAS_EBOOT_EFI_USB2_HC_PROTOCOL_GUID, "USB host" },
|
||||
{ VAS_EBOOT_EFI_DEBUG_SUPPORT_PROTOCOL_GUID, "debug support" },
|
||||
{ VAS_EBOOT_EFI_DEBUGPORT_PROTOCOL_GUID, "debug port" },
|
||||
{ VAS_EBOOT_EFI_DECOMPRESS_PROTOCOL_GUID, "decompress" },
|
||||
{ VAS_EBOOT_EFI_LOADED_IMAGE_PROTOCOL_GUID, "loaded image" },
|
||||
{ VAS_EBOOT_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID, "device path to text" },
|
||||
{ VAS_EBOOT_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID, "device path utilities" },
|
||||
{ VAS_EBOOT_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID, "device path from text" },
|
||||
{ VAS_EBOOT_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID, "HII config routing" },
|
||||
{ VAS_EBOOT_EFI_HII_DATABASE_PROTOCOL_GUID, "HII database" },
|
||||
{ VAS_EBOOT_EFI_HII_STRING_PROTOCOL_GUID, "HII string" },
|
||||
{ VAS_EBOOT_EFI_HII_IMAGE_PROTOCOL_GUID, "HII image" },
|
||||
{ VAS_EBOOT_EFI_HII_FONT_PROTOCOL_GUID, "HII font" },
|
||||
{ VAS_EBOOT_EFI_COMPONENT_NAME2_PROTOCOL_GUID, "component name 2" },
|
||||
{ VAS_EBOOT_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID,
|
||||
"HII configuration access" },
|
||||
{ VAS_EBOOT_EFI_USB_IO_PROTOCOL_GUID, "USB I/O" },
|
||||
};
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_lsefi (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_efi_handle_t *handles;
|
||||
VasEBoot_efi_uintn_t num_handles;
|
||||
unsigned i, j, k;
|
||||
|
||||
handles = VasEBoot_efi_locate_handle (VAS_EBOOT_EFI_ALL_HANDLES,
|
||||
NULL, NULL, &num_handles);
|
||||
|
||||
for (i = 0; i < num_handles; i++)
|
||||
{
|
||||
VasEBoot_efi_handle_t handle = handles[i];
|
||||
VasEBoot_efi_status_t status;
|
||||
VasEBoot_efi_uintn_t num_protocols;
|
||||
VasEBoot_packed_guid_t **protocols;
|
||||
VasEBoot_efi_device_path_t *dp;
|
||||
|
||||
VasEBoot_printf ("Handle %p\n", handle);
|
||||
|
||||
dp = VasEBoot_efi_get_device_path (handle);
|
||||
if (dp)
|
||||
{
|
||||
VasEBoot_printf (" ");
|
||||
VasEBoot_efi_print_device_path (dp);
|
||||
}
|
||||
|
||||
status = VasEBoot_efi_system_table->boot_services->protocols_per_handle (handle,
|
||||
&protocols,
|
||||
&num_protocols);
|
||||
if (status != VAS_EBOOT_EFI_SUCCESS) {
|
||||
VasEBoot_printf ("Unable to retrieve protocols\n");
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < num_protocols; j++)
|
||||
{
|
||||
for (k = 0; k < ARRAY_SIZE (known_protocols); k++)
|
||||
if (VasEBoot_memcmp (protocols[j], &known_protocols[k].guid,
|
||||
sizeof (known_protocols[k].guid)) == 0)
|
||||
break;
|
||||
if (k < ARRAY_SIZE (known_protocols))
|
||||
VasEBoot_printf (" %s\n", known_protocols[k].name);
|
||||
else
|
||||
VasEBoot_printf (" %pG\n", protocols[j]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VasEBoot_free (handles);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(lsefi)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("lsefi", VasEBoot_cmd_lsefi,
|
||||
NULL, "Display EFI handles.");
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(lsefi)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
/* lsefimemmap.c - Display memory map. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/command.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define ADD_MEMORY_DESCRIPTOR(desc, size) \
|
||||
((VasEBoot_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_lsefimmap (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_efi_uintn_t map_size;
|
||||
VasEBoot_efi_memory_descriptor_t *memory_map;
|
||||
VasEBoot_efi_memory_descriptor_t *memory_map_end;
|
||||
VasEBoot_efi_memory_descriptor_t *desc;
|
||||
VasEBoot_efi_uintn_t desc_size;
|
||||
|
||||
map_size = 0;
|
||||
if (VasEBoot_efi_get_memory_map (&map_size, NULL, NULL, &desc_size, 0) < 0)
|
||||
return 0;
|
||||
|
||||
memory_map = VasEBoot_malloc (map_size);
|
||||
if (memory_map == NULL)
|
||||
return VasEBoot_errno;
|
||||
if (VasEBoot_efi_get_memory_map (&map_size, memory_map, NULL, &desc_size, 0) <= 0)
|
||||
goto fail;
|
||||
|
||||
VasEBoot_printf
|
||||
("Type Physical start - end #Pages "
|
||||
" Size Attributes\n");
|
||||
memory_map_end = ADD_MEMORY_DESCRIPTOR (memory_map, map_size);
|
||||
for (desc = memory_map;
|
||||
desc < memory_map_end;
|
||||
desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||
{
|
||||
VasEBoot_efi_uint64_t size;
|
||||
VasEBoot_efi_uint64_t attr;
|
||||
static const char types_str[][9] =
|
||||
{
|
||||
"reserved",
|
||||
"ldr-code",
|
||||
"ldr-data",
|
||||
"BS-code ",
|
||||
"BS-data ",
|
||||
"RT-code ",
|
||||
"RT-data ",
|
||||
"conv-mem",
|
||||
"unusable",
|
||||
"ACPI-rec",
|
||||
"ACPI-nvs",
|
||||
"MMIO ",
|
||||
"IO-ports",
|
||||
"PAL-code",
|
||||
"persist ",
|
||||
};
|
||||
if (desc->type < ARRAY_SIZE (types_str))
|
||||
VasEBoot_printf ("%s ", types_str[desc->type]);
|
||||
else
|
||||
VasEBoot_printf ("Unk %02x ", desc->type);
|
||||
|
||||
VasEBoot_printf (" %016" PRIxVAS_EBOOT_UINT64_T "-%016" PRIxVAS_EBOOT_UINT64_T
|
||||
" %08" PRIxVAS_EBOOT_UINT64_T,
|
||||
desc->physical_start,
|
||||
desc->physical_start + (desc->num_pages << 12) - 1,
|
||||
desc->num_pages);
|
||||
|
||||
size = desc->num_pages << 12; /* 4 KiB page size */
|
||||
/*
|
||||
* Since size is a multiple of 4 KiB, no need to handle units
|
||||
* of just Bytes (which would use a mask of 0x3ff).
|
||||
*
|
||||
* 14 characters would support the largest possible number of 4 KiB
|
||||
* pages that are not a multiple of larger units (e.g., MiB):
|
||||
* 17592186044415 (0xffffff_fffff000), but that uses a lot of
|
||||
* whitespace for a rare case. 6 characters usually suffices;
|
||||
* columns will be off if not, but this is preferable to rounding.
|
||||
*/
|
||||
if (size & 0xfffff)
|
||||
VasEBoot_printf (" %6" PRIuVAS_EBOOT_UINT64_T "KiB", size >> 10);
|
||||
else if (size & 0x3fffffff)
|
||||
VasEBoot_printf (" %6" PRIuVAS_EBOOT_UINT64_T "MiB", size >> 20);
|
||||
else if (size & 0xffffffffff)
|
||||
VasEBoot_printf (" %6" PRIuVAS_EBOOT_UINT64_T "GiB", size >> 30);
|
||||
else if (size & 0x3ffffffffffff)
|
||||
VasEBoot_printf (" %6" PRIuVAS_EBOOT_UINT64_T "TiB", size >> 40);
|
||||
else if (size & 0xfffffffffffffff)
|
||||
VasEBoot_printf (" %6" PRIuVAS_EBOOT_UINT64_T "PiB", size >> 50);
|
||||
else
|
||||
VasEBoot_printf (" %6" PRIuVAS_EBOOT_UINT64_T "EiB", size >> 60);
|
||||
|
||||
attr = desc->attribute;
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_RUNTIME)
|
||||
VasEBoot_printf (" RT");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_UC)
|
||||
VasEBoot_printf (" UC");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_WC)
|
||||
VasEBoot_printf (" WC");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_WT)
|
||||
VasEBoot_printf (" WT");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_WB)
|
||||
VasEBoot_printf (" WB");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_UCE)
|
||||
VasEBoot_printf (" UCE");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_WP)
|
||||
VasEBoot_printf (" WP");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_RP)
|
||||
VasEBoot_printf (" RP");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_XP)
|
||||
VasEBoot_printf (" XP");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_NV)
|
||||
VasEBoot_printf (" NV");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_MORE_RELIABLE)
|
||||
VasEBoot_printf (" MR");
|
||||
if (attr & VAS_EBOOT_EFI_MEMORY_RO)
|
||||
VasEBoot_printf (" RO");
|
||||
|
||||
VasEBoot_printf ("\n");
|
||||
}
|
||||
|
||||
fail:
|
||||
VasEBoot_free (memory_map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(lsefimmap)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("lsefimmap", VasEBoot_cmd_lsefimmap,
|
||||
"", "Display EFI memory map.");
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(lsefimmap)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/* lsefisystab.c - Display EFI systab. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/normal.h>
|
||||
#include <VasEBoot/charset.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
struct guid_mapping
|
||||
{
|
||||
VasEBoot_guid_t guid;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct guid_mapping guid_mappings[] =
|
||||
{
|
||||
{ VAS_EBOOT_EFI_ACPI_20_TABLE_GUID, "ACPI-2.0"},
|
||||
{ VAS_EBOOT_EFI_ACPI_TABLE_GUID, "ACPI-1.0"},
|
||||
{ VAS_EBOOT_EFI_CONFORMANCE_PROFILES_TABLE_GUID, "CONFORMANCE PROFILES"},
|
||||
{ VAS_EBOOT_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID,
|
||||
"CRC32 GUIDED SECTION EXTRACTION"},
|
||||
{ VAS_EBOOT_EFI_DEBUG_IMAGE_INFO_TABLE_GUID, "DEBUG IMAGE INFO"},
|
||||
{ VAS_EBOOT_EFI_DEVICE_TREE_GUID, "DEVICE TREE"},
|
||||
{ VAS_EBOOT_EFI_DXE_SERVICES_TABLE_GUID, "DXE SERVICES"},
|
||||
{ VAS_EBOOT_EFI_HCDP_TABLE_GUID, "HCDP"},
|
||||
{ VAS_EBOOT_EFI_HOB_LIST_GUID, "HOB LIST"},
|
||||
{ VAS_EBOOT_EFI_IMAGE_SECURITY_DATABASE_GUID, "IMAGE EXECUTION INFORMATION"},
|
||||
{ VAS_EBOOT_EFI_LZMA_CUSTOM_DECOMPRESS_GUID, "LZMA CUSTOM DECOMPRESS"},
|
||||
{ VAS_EBOOT_EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMORY ATTRIBUTES TABLE"},
|
||||
{ VAS_EBOOT_EFI_MEMORY_TYPE_INFORMATION_GUID, "MEMORY TYPE INFO"},
|
||||
{ VAS_EBOOT_EFI_MPS_TABLE_GUID, "MPS"},
|
||||
{ VAS_EBOOT_EFI_RT_PROPERTIES_TABLE_GUID, "RT PROPERTIES"},
|
||||
{ VAS_EBOOT_EFI_SAL_TABLE_GUID, "SAL"},
|
||||
{ VAS_EBOOT_EFI_SMBIOS_TABLE_GUID, "SMBIOS"},
|
||||
{ VAS_EBOOT_EFI_SMBIOS3_TABLE_GUID, "SMBIOS3"},
|
||||
{ VAS_EBOOT_EFI_SYSTEM_RESOURCE_TABLE_GUID, "SYSTEM RESOURCE TABLE"},
|
||||
{ VAS_EBOOT_EFI_TCG2_FINAL_EVENTS_TABLE_GUID, "TCG2 FINAL EVENTS TABLE"},
|
||||
{ VAS_EBOOT_EFI_TIANO_CUSTOM_DECOMPRESS_GUID, "TIANO CUSTOM DECOMPRESS"},
|
||||
{ VAS_EBOOT_EFI_TSC_FREQUENCY_GUID, "TSC FREQUENCY"},
|
||||
};
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_lsefisystab (struct VasEBoot_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
const VasEBoot_efi_system_table_t *st = VasEBoot_efi_system_table;
|
||||
const VasEBoot_efi_uint32_t major_rev = st->hdr.revision >> 16;
|
||||
const VasEBoot_efi_uint32_t minor_rev_upper = (st->hdr.revision & 0xffff) / 10;
|
||||
const VasEBoot_efi_uint32_t minor_rev_lower = (st->hdr.revision & 0xffff) % 10;
|
||||
VasEBoot_efi_configuration_table_t *t;
|
||||
unsigned int i;
|
||||
|
||||
VasEBoot_printf ("Address: %p\n", st);
|
||||
VasEBoot_printf ("Signature: %016" PRIxVAS_EBOOT_UINT64_T " revision: %u.%u",
|
||||
st->hdr.signature, major_rev, minor_rev_upper);
|
||||
if (minor_rev_lower)
|
||||
VasEBoot_printf (".%u", minor_rev_lower);
|
||||
VasEBoot_printf ("\n");
|
||||
{
|
||||
char *vendor;
|
||||
VasEBoot_uint16_t *vendor_utf16;
|
||||
VasEBoot_printf ("Vendor: ");
|
||||
|
||||
for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++);
|
||||
/* Allocate extra 3 bytes to simplify math. */
|
||||
vendor = VasEBoot_calloc (4, vendor_utf16 - st->firmware_vendor + 1);
|
||||
if (!vendor)
|
||||
return VasEBoot_errno;
|
||||
*VasEBoot_utf16_to_utf8 ((VasEBoot_uint8_t *) vendor, st->firmware_vendor,
|
||||
vendor_utf16 - st->firmware_vendor) = 0;
|
||||
VasEBoot_printf ("%s", vendor);
|
||||
VasEBoot_free (vendor);
|
||||
}
|
||||
|
||||
VasEBoot_printf (", Version=%x\n", st->firmware_revision);
|
||||
|
||||
VasEBoot_printf ("%lld tables:\n", (long long) st->num_table_entries);
|
||||
t = st->configuration_table;
|
||||
for (i = 0; i < st->num_table_entries; i++)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
VasEBoot_printf ("%p ", t->vendor_table);
|
||||
|
||||
VasEBoot_printf ("%pG", &t->vendor_guid);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE (guid_mappings); j++)
|
||||
if (VasEBoot_memcmp (&guid_mappings[j].guid, &t->vendor_guid,
|
||||
sizeof (VasEBoot_guid_t)) == 0)
|
||||
VasEBoot_printf (" %s", guid_mappings[j].name);
|
||||
|
||||
VasEBoot_printf ("\n");
|
||||
t++;
|
||||
}
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(lsefisystab)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("lsefisystab", VasEBoot_cmd_lsefisystab,
|
||||
"", "Display EFI system tables.");
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(lsefisystab)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/* lssal.c - Display EFI SAL systab. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <VasEBoot/types.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/normal.h>
|
||||
#include <VasEBoot/charset.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static void
|
||||
disp_sal (void *table)
|
||||
{
|
||||
struct VasEBoot_efi_sal_system_table *t = table;
|
||||
void *desc;
|
||||
VasEBoot_uint32_t len, l, i;
|
||||
|
||||
VasEBoot_printf ("SAL rev: %02x, signature: %x, len:%x\n",
|
||||
t->sal_rev, t->signature, t->total_table_len);
|
||||
VasEBoot_printf ("nbr entry: %d, chksum: %02x, SAL version A: %02x B: %02x\n",
|
||||
t->entry_count, t->checksum,
|
||||
t->sal_a_version, t->sal_b_version);
|
||||
VasEBoot_printf ("OEM-ID: %-32s\n", t->oem_id);
|
||||
VasEBoot_printf ("Product-ID: %-32s\n", t->product_id);
|
||||
|
||||
desc = t->entries;
|
||||
len = t->total_table_len - sizeof (struct VasEBoot_efi_sal_system_table);
|
||||
if (t->total_table_len <= sizeof (struct VasEBoot_efi_sal_system_table))
|
||||
return;
|
||||
for (i = 0; i < t->entry_count; i++)
|
||||
{
|
||||
switch (*(VasEBoot_uint8_t *) desc)
|
||||
{
|
||||
case VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR:
|
||||
{
|
||||
struct VasEBoot_efi_sal_system_table_entrypoint_descriptor *c = desc;
|
||||
l = sizeof (*c);
|
||||
VasEBoot_printf (" Entry point: PAL=%016" PRIxVAS_EBOOT_UINT64_T
|
||||
" SAL=%016" PRIxVAS_EBOOT_UINT64_T " GP=%016"
|
||||
PRIxVAS_EBOOT_UINT64_T "\n",
|
||||
c->pal_proc_addr, c->sal_proc_addr,
|
||||
c->global_data_ptr);
|
||||
}
|
||||
break;
|
||||
case VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR:
|
||||
{
|
||||
struct VasEBoot_efi_sal_system_table_memory_descriptor *c = desc;
|
||||
l = sizeof (*c);
|
||||
VasEBoot_printf (" Memory descriptor entry addr=%016" PRIxVAS_EBOOT_UINT64_T
|
||||
" len=%" PRIuVAS_EBOOT_UINT64_T "KB\n",
|
||||
c->addr, c->len * 4);
|
||||
VasEBoot_printf (" sal_used=%d attr=%x AR=%x attr_mask=%x "
|
||||
"type=%x usage=%x\n",
|
||||
c->sal_used, c->attr, c->ar, c->attr_mask, c->mem_type,
|
||||
c->usage);
|
||||
}
|
||||
break;
|
||||
case VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES:
|
||||
{
|
||||
struct VasEBoot_efi_sal_system_table_platform_features *c = desc;
|
||||
l = sizeof (*c);
|
||||
VasEBoot_printf (" Platform features: %02x", c->flags);
|
||||
if (c->flags & VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK)
|
||||
VasEBoot_printf (" BusLock");
|
||||
if (c->flags & VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT)
|
||||
VasEBoot_printf (" IrqRedirect");
|
||||
if (c->flags & VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT)
|
||||
|
||||
VasEBoot_printf (" IPIRedirect");
|
||||
if (c->flags & VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT)
|
||||
|
||||
VasEBoot_printf (" ITCDrift");
|
||||
VasEBoot_printf ("\n");
|
||||
}
|
||||
break;
|
||||
case VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR:
|
||||
{
|
||||
struct VasEBoot_efi_sal_system_table_translation_register_descriptor *c
|
||||
= desc;
|
||||
l = sizeof (*c);
|
||||
VasEBoot_printf (" TR type=%d num=%d va=%016" PRIxVAS_EBOOT_UINT64_T
|
||||
" pte=%016" PRIxVAS_EBOOT_UINT64_T "\n",
|
||||
c->register_type, c->register_number,
|
||||
c->addr, c->page_size);
|
||||
}
|
||||
break;
|
||||
case VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE:
|
||||
{
|
||||
struct VasEBoot_efi_sal_system_table_purge_translation_coherence *c
|
||||
= desc;
|
||||
l = sizeof (*c);
|
||||
VasEBoot_printf (" PTC coherence nbr=%d addr=%016" PRIxVAS_EBOOT_UINT64_T "\n",
|
||||
c->ndomains, c->coherence);
|
||||
}
|
||||
break;
|
||||
case VAS_EBOOT_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP:
|
||||
{
|
||||
struct VasEBoot_efi_sal_system_table_ap_wakeup *c = desc;
|
||||
l = sizeof (*c);
|
||||
VasEBoot_printf (" AP wake-up: mec=%d vect=%" PRIxVAS_EBOOT_UINT64_T "\n",
|
||||
c->mechanism, c->vector);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
VasEBoot_printf (" unknown entry 0x%x\n", *(VasEBoot_uint8_t *)desc);
|
||||
return;
|
||||
}
|
||||
desc = (VasEBoot_uint8_t *)desc + l;
|
||||
if (len <= l)
|
||||
return;
|
||||
len -= l;
|
||||
}
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_lssal (struct VasEBoot_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
static VasEBoot_guid_t guid = VAS_EBOOT_EFI_SAL_TABLE_GUID;
|
||||
void *table = VasEBoot_efi_find_configuration_table (&guid);
|
||||
|
||||
if (table == NULL)
|
||||
{
|
||||
VasEBoot_printf ("SAL not found\n");
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
disp_sal (table);
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(lssal)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("lssal", VasEBoot_cmd_lssal, "",
|
||||
"Display SAL system table.");
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(lssal)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/* smbios.c - get smbios tables. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/smbios.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
|
||||
struct VasEBoot_smbios_eps *
|
||||
VasEBoot_machine_smbios_get_eps (void)
|
||||
{
|
||||
static VasEBoot_guid_t smbios_guid = VAS_EBOOT_EFI_SMBIOS_TABLE_GUID;
|
||||
|
||||
return (struct VasEBoot_smbios_eps *) VasEBoot_efi_find_configuration_table (&smbios_guid);
|
||||
}
|
||||
|
||||
struct VasEBoot_smbios_eps3 *
|
||||
VasEBoot_machine_smbios_get_eps3 (void)
|
||||
{
|
||||
static VasEBoot_guid_t smbios3_guid = VAS_EBOOT_EFI_SMBIOS3_TABLE_GUID;
|
||||
|
||||
return (struct VasEBoot_smbios_eps3 *) VasEBoot_efi_find_configuration_table (&smbios3_guid);
|
||||
}
|
||||
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* EFI TPM support code.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/err.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/efi/api.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/efi/cc.h>
|
||||
#include <VasEBoot/efi/tpm.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/tpm.h>
|
||||
#include <VasEBoot/term.h>
|
||||
|
||||
typedef TCG_PCR_EVENT VasEBoot_tpm_event_t;
|
||||
|
||||
static VasEBoot_guid_t tpm_guid = EFI_TPM_GUID;
|
||||
static VasEBoot_guid_t tpm2_guid = EFI_TPM2_GUID;
|
||||
static VasEBoot_guid_t cc_measurement_guid = VAS_EBOOT_EFI_CC_MEASUREMENT_PROTOCOL_GUID;
|
||||
|
||||
static VasEBoot_efi_handle_t *VasEBoot_tpm_handle;
|
||||
static VasEBoot_uint8_t VasEBoot_tpm_version;
|
||||
|
||||
static VasEBoot_int8_t tpm1_present = -1;
|
||||
static VasEBoot_int8_t tpm2_present = -1;
|
||||
static VasEBoot_efi_int64_t tpm2_active_pcr_banks = -1;
|
||||
|
||||
static VasEBoot_efi_boolean_t
|
||||
VasEBoot_tpm1_present (VasEBoot_efi_tpm_protocol_t *tpm)
|
||||
{
|
||||
VasEBoot_efi_status_t status;
|
||||
TCG_EFI_BOOT_SERVICE_CAPABILITY caps;
|
||||
VasEBoot_uint32_t flags;
|
||||
VasEBoot_efi_physical_address_t eventlog, lastevent;
|
||||
|
||||
if (tpm1_present != -1)
|
||||
return (VasEBoot_efi_boolean_t) tpm1_present;
|
||||
|
||||
caps.Size = (VasEBoot_uint8_t) sizeof (caps);
|
||||
|
||||
status = tpm->status_check (tpm, &caps, &flags, &eventlog, &lastevent);
|
||||
|
||||
if (status != VAS_EBOOT_EFI_SUCCESS || caps.TPMDeactivatedFlag
|
||||
|| !caps.TPMPresentFlag)
|
||||
tpm1_present = 0;
|
||||
else
|
||||
tpm1_present = 1;
|
||||
|
||||
VasEBoot_dprintf ("tpm", "tpm1%s present\n", tpm1_present ? "" : " NOT");
|
||||
|
||||
return (VasEBoot_efi_boolean_t) tpm1_present;
|
||||
}
|
||||
|
||||
static VasEBoot_efi_boolean_t
|
||||
VasEBoot_tpm2_present (VasEBoot_efi_tpm2_protocol_t *tpm)
|
||||
{
|
||||
VasEBoot_efi_status_t status;
|
||||
EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
|
||||
|
||||
caps.Size = (VasEBoot_uint8_t) sizeof (caps);
|
||||
|
||||
if (tpm2_present != -1)
|
||||
return (VasEBoot_efi_boolean_t) tpm2_present;
|
||||
|
||||
status = tpm->get_capability (tpm, &caps);
|
||||
|
||||
if (status != VAS_EBOOT_EFI_SUCCESS || !caps.TPMPresentFlag)
|
||||
tpm2_present = 0;
|
||||
else
|
||||
tpm2_present = 1;
|
||||
|
||||
VasEBoot_dprintf ("tpm", "tpm2%s present\n", tpm2_present ? "" : " NOT");
|
||||
|
||||
return (VasEBoot_efi_boolean_t) tpm2_present;
|
||||
}
|
||||
|
||||
static VasEBoot_efi_boolean_t
|
||||
VasEBoot_tpm_handle_find (VasEBoot_efi_handle_t *tpm_handle,
|
||||
VasEBoot_efi_uint8_t *protocol_version)
|
||||
{
|
||||
VasEBoot_efi_handle_t *handles;
|
||||
VasEBoot_efi_uintn_t num_handles;
|
||||
|
||||
if (VasEBoot_tpm_handle != NULL)
|
||||
{
|
||||
*tpm_handle = VasEBoot_tpm_handle;
|
||||
*protocol_version = VasEBoot_tpm_version;
|
||||
return 1;
|
||||
}
|
||||
|
||||
handles = VasEBoot_efi_locate_handle (VAS_EBOOT_EFI_BY_PROTOCOL, &tpm_guid, NULL,
|
||||
&num_handles);
|
||||
if (handles && num_handles > 0)
|
||||
{
|
||||
VasEBoot_tpm_handle = handles[0];
|
||||
*tpm_handle = handles[0];
|
||||
VasEBoot_tpm_version = 1;
|
||||
*protocol_version = 1;
|
||||
VasEBoot_dprintf ("tpm", "TPM handle Found, version: 1\n");
|
||||
VasEBoot_free (handles);
|
||||
return 1;
|
||||
}
|
||||
|
||||
handles = VasEBoot_efi_locate_handle (VAS_EBOOT_EFI_BY_PROTOCOL, &tpm2_guid, NULL,
|
||||
&num_handles);
|
||||
if (handles && num_handles > 0)
|
||||
{
|
||||
VasEBoot_tpm_handle = handles[0];
|
||||
*tpm_handle = handles[0];
|
||||
VasEBoot_tpm_version = 2;
|
||||
*protocol_version = 2;
|
||||
VasEBoot_dprintf ("tpm", "TPM handle Found, version: 2\n");
|
||||
VasEBoot_free (handles);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_efi_log_event_status (VasEBoot_efi_status_t status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case VAS_EBOOT_EFI_SUCCESS:
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
case VAS_EBOOT_EFI_DEVICE_ERROR:
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_IO, N_("command failed"));
|
||||
case VAS_EBOOT_EFI_INVALID_PARAMETER:
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("invalid parameter"));
|
||||
case VAS_EBOOT_EFI_BUFFER_TOO_SMALL:
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("output buffer too small"));
|
||||
case VAS_EBOOT_EFI_NOT_FOUND:
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_UNKNOWN_DEVICE, N_("TPM unavailable"));
|
||||
default:
|
||||
return VasEBoot_error (VasEBoot_is_tpm_fail_fatal () ? VAS_EBOOT_ERR_UNKNOWN_DEVICE : VAS_EBOOT_ERR_NONE, N_("unknown TPM error"));
|
||||
}
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_tpm1_log_event (VasEBoot_efi_handle_t tpm_handle, unsigned char *buf,
|
||||
VasEBoot_size_t size, VasEBoot_uint8_t pcr,
|
||||
const char *description)
|
||||
{
|
||||
VasEBoot_tpm_event_t *event;
|
||||
VasEBoot_efi_status_t status;
|
||||
VasEBoot_efi_tpm_protocol_t *tpm;
|
||||
VasEBoot_efi_physical_address_t lastevent;
|
||||
VasEBoot_uint32_t algorithm;
|
||||
VasEBoot_uint32_t eventnum = 0;
|
||||
|
||||
tpm = VasEBoot_efi_open_protocol (tpm_handle, &tpm_guid,
|
||||
VAS_EBOOT_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
|
||||
if (!VasEBoot_tpm1_present (tpm))
|
||||
return 0;
|
||||
|
||||
event = VasEBoot_zalloc (sizeof (*event) + VasEBoot_strlen (description) + 1);
|
||||
if (!event)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
N_("cannot allocate TPM event buffer"));
|
||||
|
||||
event->PCRIndex = pcr;
|
||||
event->EventType = EV_IPL;
|
||||
event->EventSize = VasEBoot_strlen (description) + 1;
|
||||
VasEBoot_strcpy ((char *) event->Event, description);
|
||||
|
||||
algorithm = TCG_ALG_SHA;
|
||||
status = tpm->log_extend_event (tpm, (VasEBoot_addr_t) buf, (VasEBoot_uint64_t) size,
|
||||
algorithm, event, &eventnum, &lastevent);
|
||||
VasEBoot_free (event);
|
||||
|
||||
return VasEBoot_efi_log_event_status (status);
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_tpm2_log_event (VasEBoot_efi_handle_t tpm_handle, unsigned char *buf,
|
||||
VasEBoot_size_t size, VasEBoot_uint8_t pcr,
|
||||
const char *description)
|
||||
{
|
||||
EFI_TCG2_EVENT *event;
|
||||
VasEBoot_efi_status_t status;
|
||||
VasEBoot_efi_tpm2_protocol_t *tpm;
|
||||
|
||||
tpm = VasEBoot_efi_open_protocol (tpm_handle, &tpm2_guid,
|
||||
VAS_EBOOT_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
|
||||
if (!VasEBoot_tpm2_present (tpm))
|
||||
return 0;
|
||||
|
||||
event =
|
||||
VasEBoot_zalloc (sizeof (EFI_TCG2_EVENT) + VasEBoot_strlen (description) + 1);
|
||||
if (!event)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY,
|
||||
N_("cannot allocate TPM event buffer"));
|
||||
|
||||
event->Header.HeaderSize = sizeof (EFI_TCG2_EVENT_HEADER);
|
||||
event->Header.HeaderVersion = 1;
|
||||
event->Header.PCRIndex = pcr;
|
||||
event->Header.EventType = EV_IPL;
|
||||
event->Size =
|
||||
sizeof (*event) - sizeof (event->Event) + VasEBoot_strlen (description) + 1;
|
||||
VasEBoot_strcpy ((char *) event->Event, description);
|
||||
|
||||
status = tpm->hash_log_extend_event (tpm, 0, (VasEBoot_addr_t) buf,
|
||||
(VasEBoot_uint64_t) size, event);
|
||||
VasEBoot_free (event);
|
||||
|
||||
return VasEBoot_efi_log_event_status (status);
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_cc_log_event (unsigned char *buf, VasEBoot_size_t size, VasEBoot_uint8_t pcr,
|
||||
const char *description)
|
||||
{
|
||||
VasEBoot_efi_cc_event_t *event;
|
||||
VasEBoot_efi_status_t status;
|
||||
VasEBoot_efi_cc_protocol_t *cc;
|
||||
VasEBoot_efi_cc_mr_index_t mr;
|
||||
|
||||
cc = VasEBoot_efi_locate_protocol (&cc_measurement_guid, NULL);
|
||||
if (cc == NULL)
|
||||
return;
|
||||
|
||||
status = cc->map_pcr_to_mr_index (cc, pcr, &mr);
|
||||
if (status != VAS_EBOOT_EFI_SUCCESS)
|
||||
{
|
||||
VasEBoot_efi_log_event_status (status);
|
||||
return;
|
||||
}
|
||||
|
||||
event = VasEBoot_zalloc (sizeof (VasEBoot_efi_cc_event_t) +
|
||||
VasEBoot_strlen (description) + 1);
|
||||
if (event == NULL)
|
||||
{
|
||||
VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY, N_("cannot allocate CC event buffer"));
|
||||
return;
|
||||
}
|
||||
|
||||
event->Header.HeaderSize = sizeof (VasEBoot_efi_cc_event_header_t);
|
||||
event->Header.HeaderVersion = VAS_EBOOT_EFI_CC_EVENT_HEADER_VERSION;
|
||||
event->Header.MrIndex = mr;
|
||||
event->Header.EventType = EV_IPL;
|
||||
event->Size = sizeof (*event) + VasEBoot_strlen (description) + 1;
|
||||
VasEBoot_strcpy ((char *) event->Event, description);
|
||||
|
||||
status = cc->hash_log_extend_event (cc, 0,
|
||||
(VasEBoot_efi_physical_address_t)(VasEBoot_addr_t) buf,
|
||||
(VasEBoot_efi_uint64_t) size, event);
|
||||
VasEBoot_free (event);
|
||||
|
||||
if (status != VAS_EBOOT_EFI_SUCCESS)
|
||||
VasEBoot_efi_log_event_status (status);
|
||||
}
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_tpm_measure (unsigned char *buf, VasEBoot_size_t size, VasEBoot_uint8_t pcr,
|
||||
const char *description)
|
||||
{
|
||||
VasEBoot_efi_handle_t tpm_handle;
|
||||
VasEBoot_efi_uint8_t protocol_version;
|
||||
|
||||
VasEBoot_cc_log_event(buf, size, pcr, description);
|
||||
|
||||
if (!VasEBoot_tpm_handle_find (&tpm_handle, &protocol_version))
|
||||
return 0;
|
||||
|
||||
VasEBoot_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxVAS_EBOOT_SIZE ", %s\n",
|
||||
pcr, size, description);
|
||||
|
||||
if (protocol_version == 1)
|
||||
return VasEBoot_tpm1_log_event (tpm_handle, buf, size, pcr, description);
|
||||
else
|
||||
return VasEBoot_tpm2_log_event (tpm_handle, buf, size, pcr, description);
|
||||
}
|
||||
|
||||
int
|
||||
VasEBoot_tpm_present (void)
|
||||
{
|
||||
VasEBoot_efi_handle_t tpm_handle;
|
||||
VasEBoot_efi_uint8_t protocol_version;
|
||||
VasEBoot_efi_cc_protocol_t *cc;
|
||||
|
||||
/*
|
||||
* When confidential computing measurement protocol is enabled
|
||||
* we assume the TPM is present.
|
||||
*/
|
||||
cc = VasEBoot_efi_locate_protocol (&cc_measurement_guid, NULL);
|
||||
if (cc != NULL)
|
||||
return 1;
|
||||
|
||||
if (!VasEBoot_tpm_handle_find (&tpm_handle, &protocol_version))
|
||||
return 0;
|
||||
|
||||
if (protocol_version == 1)
|
||||
{
|
||||
VasEBoot_efi_tpm_protocol_t *tpm;
|
||||
|
||||
tpm = VasEBoot_efi_open_protocol (tpm_handle, &tpm_guid,
|
||||
VAS_EBOOT_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (!tpm)
|
||||
{
|
||||
VasEBoot_dprintf ("tpm", "Cannot open TPM protocol\n");
|
||||
return 0;
|
||||
}
|
||||
return VasEBoot_tpm1_present (tpm);
|
||||
}
|
||||
else
|
||||
{
|
||||
VasEBoot_efi_tpm2_protocol_t *tpm;
|
||||
|
||||
tpm = VasEBoot_efi_open_protocol (tpm_handle, &tpm2_guid,
|
||||
VAS_EBOOT_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (!tpm)
|
||||
{
|
||||
VasEBoot_dprintf ("tpm", "Cannot open TPM protocol\n");
|
||||
return 0;
|
||||
}
|
||||
return VasEBoot_tpm2_present (tpm);
|
||||
}
|
||||
}
|
||||
|
||||
VasEBoot_uint32_t
|
||||
VasEBoot_tpm2_active_pcr_banks (void)
|
||||
{
|
||||
EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
|
||||
VasEBoot_efi_handle_t tpm_handle;
|
||||
VasEBoot_efi_uint8_t protocol_version;
|
||||
VasEBoot_efi_tpm2_protocol_t *tpm;
|
||||
VasEBoot_efi_uint32_t active_pcr_banks;
|
||||
VasEBoot_efi_status_t status;
|
||||
|
||||
if (tpm2_active_pcr_banks >= 0)
|
||||
return (VasEBoot_uint32_t) tpm2_active_pcr_banks;
|
||||
|
||||
if (!VasEBoot_tpm_handle_find (&tpm_handle, &protocol_version))
|
||||
return (VasEBoot_uint32_t) (tpm2_active_pcr_banks = 0);
|
||||
|
||||
if (protocol_version == 1)
|
||||
return (VasEBoot_uint32_t) (tpm2_active_pcr_banks = 0); /* We report TPM2 status. */
|
||||
|
||||
tpm = VasEBoot_efi_open_protocol (tpm_handle, &tpm2_guid,
|
||||
VAS_EBOOT_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (tpm == NULL)
|
||||
{
|
||||
VasEBoot_dprintf ("tpm", "Cannot open TPM2 protocol\n");
|
||||
return (VasEBoot_uint32_t) (tpm2_active_pcr_banks = 0);
|
||||
}
|
||||
|
||||
if (!VasEBoot_tpm2_present (tpm))
|
||||
return (VasEBoot_uint32_t) (tpm2_active_pcr_banks = 0);
|
||||
|
||||
caps.Size = (VasEBoot_uint8_t) sizeof (caps);
|
||||
status = tpm->get_capability (tpm, &caps);
|
||||
if (status != VAS_EBOOT_EFI_SUCCESS)
|
||||
return (VasEBoot_uint32_t) (tpm2_active_pcr_banks = 0);
|
||||
if (caps.StructureVersion.Major < 1 ||
|
||||
(caps.StructureVersion.Major == 1 && caps.StructureVersion.Minor < 1))
|
||||
/* There's a working TPM2 but without querying protocol, let userspace figure it out. */
|
||||
return (VasEBoot_uint32_t) (tpm2_active_pcr_banks = VAS_EBOOT_UINT_MAX);
|
||||
|
||||
status = tpm->get_active_pcr_banks (tpm, &active_pcr_banks);
|
||||
if (status != VAS_EBOOT_EFI_SUCCESS)
|
||||
return (VasEBoot_uint32_t) (tpm2_active_pcr_banks = 0); /* Assume none available if the call fails. */
|
||||
|
||||
return (VasEBoot_uint32_t) (tpm2_active_pcr_banks = active_pcr_banks);
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/script_sh.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/term.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_eval (VasEBoot_command_t cmd __attribute__((__unused__)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
VasEBoot_size_t size = argc; /* +1 for final zero */
|
||||
char *str, *p;
|
||||
VasEBoot_err_t ret;
|
||||
|
||||
if (argc == 0)
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
size += VasEBoot_strlen (argv[i]);
|
||||
|
||||
str = p = VasEBoot_malloc (size);
|
||||
if (!str)
|
||||
return VasEBoot_errno;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
p = VasEBoot_stpcpy (p, argv[i]);
|
||||
*p++ = ' ';
|
||||
}
|
||||
*--p = '\0';
|
||||
|
||||
ret = VasEBoot_script_execute_sourcecode (str);
|
||||
VasEBoot_free (str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(eval)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("eval", VasEBoot_cmd_eval, N_("STRING ..."),
|
||||
N_("Evaluate arguments as VAS_EBOOT commands"));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(eval)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/* extcmd.c - support extended command */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/list.h>
|
||||
#include <VasEBoot/lockdown.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/script_sh.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
VasEBoot_err_t
|
||||
VasEBoot_extcmd_dispatcher (struct VasEBoot_command *cmd, int argc, char **args,
|
||||
struct VasEBoot_script *script)
|
||||
{
|
||||
int new_argc;
|
||||
char **new_args;
|
||||
struct VasEBoot_arg_list *state;
|
||||
struct VasEBoot_extcmd_context context;
|
||||
VasEBoot_err_t ret;
|
||||
VasEBoot_extcmd_t ext = cmd->data;
|
||||
|
||||
context.state = 0;
|
||||
context.extcmd = ext;
|
||||
context.script = script;
|
||||
|
||||
if (! ext->options)
|
||||
{
|
||||
ret = (ext->func) (&context, argc, args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
state = VasEBoot_arg_list_alloc (ext, argc, args);
|
||||
if (state == NULL)
|
||||
return VasEBoot_errno;
|
||||
|
||||
if (VasEBoot_arg_parse (ext, argc, args, state, &new_args, &new_argc))
|
||||
{
|
||||
context.state = state;
|
||||
ret = (ext->func) (&context, new_argc, new_args);
|
||||
VasEBoot_free (new_args);
|
||||
VasEBoot_free (state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
VasEBoot_free (state);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_extcmd_dispatch (struct VasEBoot_command *cmd, int argc, char **args)
|
||||
{
|
||||
return VasEBoot_extcmd_dispatcher (cmd, argc, args, 0);
|
||||
}
|
||||
|
||||
VasEBoot_extcmd_t
|
||||
VasEBoot_register_extcmd_prio (const char *name, VasEBoot_extcmd_func_t func,
|
||||
VasEBoot_command_flags_t flags, const char *summary,
|
||||
const char *description,
|
||||
const struct VasEBoot_arg_option *parser,
|
||||
int prio)
|
||||
{
|
||||
VasEBoot_extcmd_t ext;
|
||||
VasEBoot_command_t cmd;
|
||||
|
||||
ext = (VasEBoot_extcmd_t) VasEBoot_malloc (sizeof (*ext));
|
||||
if (! ext)
|
||||
return 0;
|
||||
|
||||
cmd = VasEBoot_register_command_prio (name, VasEBoot_extcmd_dispatch,
|
||||
summary, description, prio);
|
||||
if (! cmd)
|
||||
{
|
||||
VasEBoot_free (ext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd->flags = (flags | VAS_EBOOT_COMMAND_FLAG_EXTCMD);
|
||||
cmd->data = ext;
|
||||
|
||||
ext->cmd = cmd;
|
||||
ext->func = func;
|
||||
ext->options = parser;
|
||||
ext->data = 0;
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
VasEBoot_extcmd_t
|
||||
VasEBoot_register_extcmd (const char *name, VasEBoot_extcmd_func_t func,
|
||||
VasEBoot_command_flags_t flags, const char *summary,
|
||||
const char *description,
|
||||
const struct VasEBoot_arg_option *parser)
|
||||
{
|
||||
return VasEBoot_register_extcmd_prio (name, func, flags,
|
||||
summary, description, parser, 1);
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_extcmd_lockdown (VasEBoot_extcmd_context_t ctxt __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **argv __attribute__ ((unused)))
|
||||
{
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_ACCESS_DENIED,
|
||||
N_("%s: the command is not allowed when lockdown is enforced"),
|
||||
ctxt->extcmd->cmd->name);
|
||||
}
|
||||
|
||||
VasEBoot_extcmd_t
|
||||
VasEBoot_register_extcmd_lockdown (const char *name, VasEBoot_extcmd_func_t func,
|
||||
VasEBoot_command_flags_t flags, const char *summary,
|
||||
const char *description,
|
||||
const struct VasEBoot_arg_option *parser)
|
||||
{
|
||||
if (VasEBoot_is_lockdown () == VAS_EBOOT_LOCKDOWN_ENABLED)
|
||||
func = VasEBoot_extcmd_lockdown;
|
||||
|
||||
return VasEBoot_register_extcmd (name, func, flags, summary, description, parser);
|
||||
}
|
||||
|
||||
void
|
||||
VasEBoot_unregister_extcmd (VasEBoot_extcmd_t ext)
|
||||
{
|
||||
if (ext == NULL)
|
||||
return;
|
||||
|
||||
VasEBoot_unregister_command (ext->cmd);
|
||||
VasEBoot_free (ext);
|
||||
}
|
||||
|
|
@ -0,0 +1,707 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/env.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/file.h>
|
||||
#include <VasEBoot/elf.h>
|
||||
#include <VasEBoot/efi/efi.h>
|
||||
#include <VasEBoot/xen_file.h>
|
||||
#include <VasEBoot/efi/pe32.h>
|
||||
#include <VasEBoot/arm/linux.h>
|
||||
#include <VasEBoot/i386/linux.h>
|
||||
#include <VasEBoot/xnu.h>
|
||||
#include <VasEBoot/machoload.h>
|
||||
#include <VasEBoot/fileid.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct VasEBoot_arg_option options[] = {
|
||||
{"is-i386-xen-pae-domu", 0, 0,
|
||||
N_("Check if FILE can be booted as i386 PAE Xen unprivileged guest kernel"),
|
||||
0, 0},
|
||||
{"is-x86_64-xen-domu", 0, 0,
|
||||
N_("Check if FILE can be booted as x86_64 Xen unprivileged guest kernel"), 0, 0},
|
||||
{"is-x86-xen-dom0", 0, 0,
|
||||
N_("Check if FILE can be used as Xen x86 privileged guest kernel"), 0, 0},
|
||||
{"is-x86-multiboot", 0, 0,
|
||||
N_("Check if FILE can be used as x86 multiboot kernel"), 0, 0},
|
||||
{"is-x86-multiboot2", 0, 0,
|
||||
N_("Check if FILE can be used as x86 multiboot2 kernel"), 0, 0},
|
||||
{"is-arm-linux", 0, 0,
|
||||
N_("Check if FILE is ARM Linux"), 0, 0},
|
||||
{"is-arm64-linux", 0, 0,
|
||||
N_("Check if FILE is ARM64 Linux"), 0, 0},
|
||||
{"is-ia64-linux", 0, 0,
|
||||
N_("Check if FILE is IA64 Linux"), 0, 0},
|
||||
{"is-mips-linux", 0, 0,
|
||||
N_("Check if FILE is MIPS Linux"), 0, 0},
|
||||
{"is-mipsel-linux", 0, 0,
|
||||
N_("Check if FILE is MIPSEL Linux"), 0, 0},
|
||||
{"is-sparc64-linux", 0, 0,
|
||||
N_("Check if FILE is SPARC64 Linux"), 0, 0},
|
||||
{"is-powerpc-linux", 0, 0,
|
||||
N_("Check if FILE is POWERPC Linux"), 0, 0},
|
||||
{"is-x86-linux", 0, 0,
|
||||
N_("Check if FILE is x86 Linux"), 0, 0},
|
||||
{"is-x86-linux32", 0, 0,
|
||||
N_("Check if FILE is x86 Linux supporting 32-bit protocol"), 0, 0},
|
||||
{"is-x86-kfreebsd", 0, 0,
|
||||
N_("Check if FILE is x86 kFreeBSD"), 0, 0},
|
||||
{"is-i386-kfreebsd", 0, 0,
|
||||
N_("Check if FILE is i386 kFreeBSD"), 0, 0},
|
||||
{"is-x86_64-kfreebsd", 0, 0,
|
||||
N_("Check if FILE is x86_64 kFreeBSD"), 0, 0},
|
||||
|
||||
{"is-x86-knetbsd", 0, 0,
|
||||
N_("Check if FILE is x86 kNetBSD"), 0, 0},
|
||||
{"is-i386-knetbsd", 0, 0,
|
||||
N_("Check if FILE is i386 kNetBSD"), 0, 0},
|
||||
{"is-x86_64-knetbsd", 0, 0,
|
||||
N_("Check if FILE is x86_64 kNetBSD"), 0, 0},
|
||||
|
||||
{"is-i386-efi", 0, 0,
|
||||
N_("Check if FILE is i386 EFI file"), 0, 0},
|
||||
{"is-x86_64-efi", 0, 0,
|
||||
N_("Check if FILE is x86_64 EFI file"), 0, 0},
|
||||
{"is-ia64-efi", 0, 0,
|
||||
N_("Check if FILE is IA64 EFI file"), 0, 0},
|
||||
{"is-arm64-efi", 0, 0,
|
||||
N_("Check if FILE is ARM64 EFI file"), 0, 0},
|
||||
{"is-arm-efi", 0, 0,
|
||||
N_("Check if FILE is ARM EFI file"), 0, 0},
|
||||
{"is-riscv32-efi", 0, 0,
|
||||
N_("Check if FILE is RISC-V 32bit EFI file"), 0, 0},
|
||||
{"is-riscv64-efi", 0, 0,
|
||||
N_("Check if FILE is RISC-V 64bit EFI file"), 0, 0},
|
||||
{"is-hibernated-hiberfil", 0, 0,
|
||||
N_("Check if FILE is hiberfil.sys in hibernated state"), 0, 0},
|
||||
{"is-x86_64-xnu", 0, 0,
|
||||
N_("Check if FILE is x86_64 XNU (Mac OS X kernel)"), 0, 0},
|
||||
{"is-i386-xnu", 0, 0,
|
||||
N_("Check if FILE is i386 XNU (Mac OS X kernel)"), 0, 0},
|
||||
{"is-xnu-hibr", 0, 0,
|
||||
N_("Check if FILE is XNU (Mac OS X kernel) hibernated image"), 0, 0},
|
||||
{"is-x86-bios-bootsector", 0, 0,
|
||||
N_("Check if FILE is BIOS bootsector"), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
IS_PAE_DOMU,
|
||||
IS_64_DOMU,
|
||||
IS_DOM0,
|
||||
IS_MULTIBOOT,
|
||||
IS_MULTIBOOT2,
|
||||
IS_ARM_LINUX,
|
||||
IS_ARM64_LINUX,
|
||||
IS_IA64_LINUX,
|
||||
IS_MIPS_LINUX,
|
||||
IS_MIPSEL_LINUX,
|
||||
IS_SPARC64_LINUX,
|
||||
IS_POWERPC_LINUX,
|
||||
IS_X86_LINUX,
|
||||
IS_X86_LINUX32,
|
||||
IS_X86_KFREEBSD,
|
||||
IS_X86_KFREEBSD32,
|
||||
IS_X86_KFREEBSD64,
|
||||
IS_X86_KNETBSD,
|
||||
IS_X86_KNETBSD32,
|
||||
IS_X86_KNETBSD64,
|
||||
IS_32_EFI,
|
||||
IS_64_EFI,
|
||||
IS_IA_EFI,
|
||||
IS_ARM64_EFI,
|
||||
IS_ARM_EFI,
|
||||
IS_RISCV32_EFI,
|
||||
IS_RISCV64_EFI,
|
||||
IS_HIBERNATED,
|
||||
IS_XNU64,
|
||||
IS_XNU32,
|
||||
IS_XNU_HIBR,
|
||||
IS_BIOS_BOOTSECTOR,
|
||||
OPT_TYPE_MIN = IS_PAE_DOMU,
|
||||
OPT_TYPE_MAX = IS_BIOS_BOOTSECTOR
|
||||
};
|
||||
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_file (VasEBoot_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
VasEBoot_file_t file = 0;
|
||||
VasEBoot_elf_t elf = 0;
|
||||
VasEBoot_err_t err;
|
||||
int type = -1, i;
|
||||
int ret = 0;
|
||||
VasEBoot_macho_t macho = 0;
|
||||
|
||||
if (argc == 0)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
for (i = OPT_TYPE_MIN; i <= OPT_TYPE_MAX; i++)
|
||||
if (ctxt->state[i].set)
|
||||
{
|
||||
if (type == -1)
|
||||
{
|
||||
type = i;
|
||||
continue;
|
||||
}
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "multiple types specified");
|
||||
}
|
||||
if (type == -1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "no type specified");
|
||||
|
||||
file = VasEBoot_file_open (args[0], VAS_EBOOT_FILE_TYPE_XNU_KERNEL);
|
||||
if (!file)
|
||||
return VasEBoot_errno;
|
||||
switch (type)
|
||||
{
|
||||
case IS_BIOS_BOOTSECTOR:
|
||||
{
|
||||
VasEBoot_uint16_t sig;
|
||||
if (VasEBoot_file_size (file) != 512)
|
||||
break;
|
||||
if (VasEBoot_file_seek (file, 510) == (VasEBoot_size_t) -1)
|
||||
break;
|
||||
if (VasEBoot_file_read (file, &sig, 2) != 2)
|
||||
break;
|
||||
if (sig != VasEBoot_cpu_to_le16_compile_time (0xaa55))
|
||||
break;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
case IS_IA64_LINUX:
|
||||
{
|
||||
Elf64_Ehdr ehdr;
|
||||
|
||||
if (VasEBoot_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|
||||
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|
||||
|| ehdr.e_ident[EI_MAG3] != ELFMAG3
|
||||
|| ehdr.e_ident[EI_VERSION] != EV_CURRENT
|
||||
|| ehdr.e_version != EV_CURRENT)
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_CLASS] != ELFCLASS64
|
||||
|| ehdr.e_ident[EI_DATA] != ELFDATA2LSB
|
||||
|| ehdr.e_machine != VasEBoot_cpu_to_le16_compile_time (EM_IA_64))
|
||||
break;
|
||||
|
||||
ret = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IS_SPARC64_LINUX:
|
||||
{
|
||||
Elf64_Ehdr ehdr;
|
||||
|
||||
if (VasEBoot_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|
||||
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|
||||
|| ehdr.e_ident[EI_MAG3] != ELFMAG3
|
||||
|| ehdr.e_ident[EI_VERSION] != EV_CURRENT
|
||||
|| ehdr.e_version != EV_CURRENT)
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_CLASS] != ELFCLASS64
|
||||
|| ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
|
||||
break;
|
||||
|
||||
if (ehdr.e_machine != VasEBoot_cpu_to_le16_compile_time (EM_SPARCV9)
|
||||
|| ehdr.e_type != VasEBoot_cpu_to_be16_compile_time (ET_EXEC))
|
||||
break;
|
||||
|
||||
ret = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IS_POWERPC_LINUX:
|
||||
{
|
||||
Elf32_Ehdr ehdr;
|
||||
|
||||
if (VasEBoot_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|
||||
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|
||||
|| ehdr.e_ident[EI_MAG3] != ELFMAG3
|
||||
|| ehdr.e_ident[EI_VERSION] != EV_CURRENT
|
||||
|| ehdr.e_version != EV_CURRENT)
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB
|
||||
|| (ehdr.e_machine != VasEBoot_cpu_to_le16_compile_time (EM_PPC)
|
||||
&& ehdr.e_machine !=
|
||||
VasEBoot_cpu_to_le16_compile_time (EM_PPC64)))
|
||||
break;
|
||||
|
||||
if (ehdr.e_type != VasEBoot_cpu_to_be16_compile_time (ET_EXEC)
|
||||
&& ehdr.e_type != VasEBoot_cpu_to_be16_compile_time (ET_DYN))
|
||||
break;
|
||||
|
||||
ret = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IS_MIPS_LINUX:
|
||||
{
|
||||
Elf32_Ehdr ehdr;
|
||||
|
||||
if (VasEBoot_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|
||||
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|
||||
|| ehdr.e_ident[EI_MAG3] != ELFMAG3
|
||||
|| ehdr.e_ident[EI_VERSION] != EV_CURRENT
|
||||
|| ehdr.e_version != EV_CURRENT)
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB
|
||||
|| ehdr.e_machine != VasEBoot_cpu_to_be16_compile_time (EM_MIPS)
|
||||
|| ehdr.e_type != VasEBoot_cpu_to_be16_compile_time (ET_EXEC))
|
||||
break;
|
||||
|
||||
ret = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IS_X86_KNETBSD:
|
||||
case IS_X86_KNETBSD32:
|
||||
case IS_X86_KNETBSD64:
|
||||
{
|
||||
int is32, is64;
|
||||
|
||||
elf = VasEBoot_elf_file (file, file->name);
|
||||
|
||||
if (elf == NULL)
|
||||
break;
|
||||
if (elf->ehdr.ehdr32.e_type != VasEBoot_cpu_to_le16_compile_time (ET_EXEC)
|
||||
|| elf->ehdr.ehdr32.e_ident[EI_DATA] != ELFDATA2LSB)
|
||||
break;
|
||||
|
||||
is32 = VasEBoot_elf_is_elf32 (elf);
|
||||
is64 = VasEBoot_elf_is_elf64 (elf);
|
||||
if (!is32 && !is64)
|
||||
break;
|
||||
if (!is32 && type == IS_X86_KNETBSD32)
|
||||
break;
|
||||
if (!is64 && type == IS_X86_KNETBSD64)
|
||||
break;
|
||||
if (is64)
|
||||
ret = VasEBoot_file_check_netbsd64 (elf);
|
||||
if (is32)
|
||||
ret = VasEBoot_file_check_netbsd32 (elf);
|
||||
break;
|
||||
}
|
||||
|
||||
case IS_X86_KFREEBSD:
|
||||
case IS_X86_KFREEBSD32:
|
||||
case IS_X86_KFREEBSD64:
|
||||
{
|
||||
Elf32_Ehdr ehdr;
|
||||
int is32, is64;
|
||||
|
||||
if (VasEBoot_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|
||||
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|
||||
|| ehdr.e_ident[EI_MAG3] != ELFMAG3
|
||||
|| ehdr.e_ident[EI_VERSION] != EV_CURRENT
|
||||
|| ehdr.e_version != EV_CURRENT)
|
||||
break;
|
||||
|
||||
if (ehdr.e_type != VasEBoot_cpu_to_le16_compile_time (ET_EXEC)
|
||||
|| ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
|
||||
break;
|
||||
|
||||
is32 = (ehdr.e_machine == VasEBoot_cpu_to_le16_compile_time (EM_386)
|
||||
&& ehdr.e_ident[EI_CLASS] == ELFCLASS32);
|
||||
is64 = (ehdr.e_machine == VasEBoot_cpu_to_le16_compile_time (EM_X86_64)
|
||||
&& ehdr.e_ident[EI_CLASS] == ELFCLASS64);
|
||||
if (!is32 && !is64)
|
||||
break;
|
||||
if (!is32 && (type == IS_X86_KFREEBSD32 || type == IS_X86_KNETBSD32))
|
||||
break;
|
||||
if (!is64 && (type == IS_X86_KFREEBSD64 || type == IS_X86_KNETBSD64))
|
||||
break;
|
||||
ret = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case IS_MIPSEL_LINUX:
|
||||
{
|
||||
Elf32_Ehdr ehdr;
|
||||
|
||||
if (VasEBoot_file_read (file, &ehdr, sizeof (ehdr)) != sizeof (ehdr))
|
||||
break;
|
||||
|
||||
if (ehdr.e_ident[EI_MAG0] != ELFMAG0
|
||||
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|
||||
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|
||||
|| ehdr.e_ident[EI_MAG3] != ELFMAG3
|
||||
|| ehdr.e_ident[EI_VERSION] != EV_CURRENT
|
||||
|| ehdr.e_version != EV_CURRENT)
|
||||
break;
|
||||
|
||||
if (ehdr.e_machine != VasEBoot_cpu_to_le16_compile_time (EM_MIPS)
|
||||
|| ehdr.e_type != VasEBoot_cpu_to_le16_compile_time (ET_EXEC))
|
||||
break;
|
||||
|
||||
ret = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
case IS_ARM_LINUX:
|
||||
{
|
||||
struct linux_arch_kernel_header lh;
|
||||
|
||||
if (VasEBoot_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
|
||||
break;
|
||||
/* Short forward branch in A32 state (for Raspberry pi kernels). */
|
||||
if (lh.code0 == VasEBoot_cpu_to_le32_compile_time (0xea000006))
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lh.magic ==
|
||||
VasEBoot_cpu_to_le32_compile_time (VAS_EBOOT_LINUX_ARM_MAGIC_SIGNATURE))
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_ARM64_LINUX:
|
||||
{
|
||||
struct linux_arch_kernel_header lh;
|
||||
|
||||
if (VasEBoot_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
|
||||
break;
|
||||
|
||||
/*
|
||||
* The PE/COFF header can be anywhere in the file. Load it from the correct
|
||||
* offset if it is not where it is expected.
|
||||
*/
|
||||
if ((VasEBoot_uint8_t *) &lh + lh.hdr_offset != (VasEBoot_uint8_t *) &lh.pe_image_header)
|
||||
{
|
||||
if (VasEBoot_file_seek (file, lh.hdr_offset) == (VasEBoot_off_t) -1
|
||||
|| VasEBoot_file_read (file, &lh.pe_image_header, sizeof (struct VasEBoot_pe_image_header))
|
||||
!= sizeof (struct VasEBoot_pe_image_header))
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_FILE_READ_ERROR, "failed to read COFF image header");
|
||||
}
|
||||
|
||||
if (lh.pe_image_header.coff_header.machine == VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_MACHINE_ARM64))
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_PAE_DOMU ... IS_DOM0:
|
||||
{
|
||||
struct VasEBoot_xen_file_info xen_inf;
|
||||
elf = VasEBoot_xen_file (file);
|
||||
if (!elf)
|
||||
break;
|
||||
err = VasEBoot_xen_get_info (elf, &xen_inf);
|
||||
if (err)
|
||||
break;
|
||||
/* Unfortuntely no way to check if kernel supports dom0. */
|
||||
if (type == IS_DOM0)
|
||||
ret = 1;
|
||||
if (type == IS_PAE_DOMU)
|
||||
ret = (xen_inf.arch == VAS_EBOOT_XEN_FILE_I386_PAE
|
||||
|| xen_inf.arch == VAS_EBOOT_XEN_FILE_I386_PAE_BIMODE);
|
||||
if (type == IS_64_DOMU)
|
||||
ret = (xen_inf.arch == VAS_EBOOT_XEN_FILE_X86_64);
|
||||
break;
|
||||
}
|
||||
case IS_MULTIBOOT:
|
||||
case IS_MULTIBOOT2:
|
||||
{
|
||||
VasEBoot_uint32_t *buffer;
|
||||
VasEBoot_ssize_t len;
|
||||
VasEBoot_size_t search_size;
|
||||
VasEBoot_uint32_t *header;
|
||||
VasEBoot_uint32_t magic;
|
||||
VasEBoot_size_t step;
|
||||
|
||||
if (type == IS_MULTIBOOT2)
|
||||
{
|
||||
search_size = 32768;
|
||||
magic = VasEBoot_cpu_to_le32_compile_time (0xe85250d6);
|
||||
step = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
search_size = 8192;
|
||||
magic = VasEBoot_cpu_to_le32_compile_time (0x1BADB002);
|
||||
step = 1;
|
||||
}
|
||||
|
||||
buffer = VasEBoot_malloc (search_size);
|
||||
if (!buffer)
|
||||
break;
|
||||
|
||||
len = VasEBoot_file_read (file, buffer, search_size);
|
||||
if (len < 32)
|
||||
{
|
||||
VasEBoot_free (buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Look for the multiboot header in the buffer. The header should
|
||||
be at least 12 bytes and aligned on a 4-byte boundary. */
|
||||
for (header = buffer;
|
||||
((char *) header <=
|
||||
(char *) buffer + len - (type == IS_MULTIBOOT2 ? 16 : 12));
|
||||
header += step)
|
||||
{
|
||||
if (header[0] == magic
|
||||
&& !(VasEBoot_le_to_cpu32 (header[0])
|
||||
+ VasEBoot_le_to_cpu32 (header[1])
|
||||
+ VasEBoot_le_to_cpu32 (header[2])
|
||||
+ (type == IS_MULTIBOOT2
|
||||
? VasEBoot_le_to_cpu32 (header[3]) : 0)))
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
VasEBoot_free (buffer);
|
||||
break;
|
||||
}
|
||||
case IS_X86_LINUX32:
|
||||
case IS_X86_LINUX:
|
||||
{
|
||||
struct linux_i386_kernel_header lh;
|
||||
if (VasEBoot_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
|
||||
break;
|
||||
if (lh.boot_flag != VasEBoot_cpu_to_le16_compile_time (0xaa55))
|
||||
break;
|
||||
|
||||
if (lh.setup_sects > VAS_EBOOT_LINUX_MAX_SETUP_SECTS)
|
||||
break;
|
||||
|
||||
/* FIXME: some really old kernels (< 1.3.73) will fail this. */
|
||||
if (lh.header !=
|
||||
VasEBoot_cpu_to_le32_compile_time (VAS_EBOOT_LINUX_I386_MAGIC_SIGNATURE)
|
||||
|| VasEBoot_le_to_cpu16 (lh.version) < 0x0200)
|
||||
break;
|
||||
|
||||
if (type == IS_X86_LINUX)
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
|
||||
still not support 32-bit boot. */
|
||||
if (lh.header !=
|
||||
VasEBoot_cpu_to_le32_compile_time (VAS_EBOOT_LINUX_I386_MAGIC_SIGNATURE)
|
||||
|| VasEBoot_le_to_cpu16 (lh.version) < 0x0203)
|
||||
break;
|
||||
|
||||
if (!(lh.loadflags & VAS_EBOOT_LINUX_FLAG_BIG_KERNEL))
|
||||
break;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
case IS_HIBERNATED:
|
||||
{
|
||||
VasEBoot_uint8_t hibr_file_magic[4];
|
||||
if (VasEBoot_file_read (file, &hibr_file_magic, sizeof (hibr_file_magic))
|
||||
!= sizeof (hibr_file_magic))
|
||||
break;
|
||||
if (VasEBoot_memcmp ("hibr", hibr_file_magic, sizeof (hibr_file_magic)) ==
|
||||
0
|
||||
|| VasEBoot_memcmp ("HIBR", hibr_file_magic,
|
||||
sizeof (hibr_file_magic)) == 0)
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
case IS_XNU64:
|
||||
case IS_XNU32:
|
||||
{
|
||||
macho = VasEBoot_macho_open (args[0], VAS_EBOOT_FILE_TYPE_XNU_KERNEL,
|
||||
(type == IS_XNU64));
|
||||
if (!macho)
|
||||
break;
|
||||
/* FIXME: more checks? */
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
case IS_XNU_HIBR:
|
||||
{
|
||||
struct VasEBoot_xnu_hibernate_header hibhead;
|
||||
if (VasEBoot_file_read (file, &hibhead, sizeof (hibhead))
|
||||
!= sizeof (hibhead))
|
||||
break;
|
||||
if (hibhead.magic !=
|
||||
VasEBoot_cpu_to_le32_compile_time (VAS_EBOOT_XNU_HIBERNATE_MAGIC))
|
||||
break;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
case IS_32_EFI:
|
||||
case IS_64_EFI:
|
||||
case IS_IA_EFI:
|
||||
case IS_ARM64_EFI:
|
||||
case IS_ARM_EFI:
|
||||
case IS_RISCV32_EFI:
|
||||
case IS_RISCV64_EFI:
|
||||
{
|
||||
char signature[4];
|
||||
VasEBoot_uint32_t pe_offset;
|
||||
struct VasEBoot_pe32_coff_header coff_head;
|
||||
|
||||
if (VasEBoot_file_read (file, signature, 2) != 2)
|
||||
break;
|
||||
if (signature[0] != 'M' || signature[1] != 'Z')
|
||||
break;
|
||||
if ((VasEBoot_ssize_t) VasEBoot_file_seek (file, 0x3c) == -1)
|
||||
break;
|
||||
if (VasEBoot_file_read (file, &pe_offset, 4) != 4)
|
||||
break;
|
||||
if ((VasEBoot_ssize_t) VasEBoot_file_seek (file, VasEBoot_le_to_cpu32 (pe_offset))
|
||||
== -1)
|
||||
break;
|
||||
if (VasEBoot_file_read (file, signature, 4) != 4)
|
||||
break;
|
||||
if (signature[0] != 'P' || signature[1] != 'E'
|
||||
|| signature[2] != '\0' || signature[3] != '\0')
|
||||
break;
|
||||
|
||||
if (VasEBoot_file_read (file, &coff_head, sizeof (coff_head))
|
||||
!= sizeof (coff_head))
|
||||
break;
|
||||
if (type == IS_32_EFI
|
||||
&& coff_head.machine !=
|
||||
VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_MACHINE_I386))
|
||||
break;
|
||||
if (type == IS_64_EFI
|
||||
&& coff_head.machine !=
|
||||
VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_MACHINE_X86_64))
|
||||
break;
|
||||
if (type == IS_IA_EFI
|
||||
&& coff_head.machine !=
|
||||
VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_MACHINE_IA64))
|
||||
break;
|
||||
if (type == IS_ARM64_EFI
|
||||
&& coff_head.machine !=
|
||||
VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_MACHINE_ARM64))
|
||||
break;
|
||||
if (type == IS_ARM_EFI
|
||||
&& coff_head.machine !=
|
||||
VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_MACHINE_ARMTHUMB_MIXED))
|
||||
break;
|
||||
if ((type == IS_RISCV32_EFI || type == IS_RISCV64_EFI)
|
||||
&& coff_head.machine !=
|
||||
VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_MACHINE_RISCV64))
|
||||
/* TODO: Determine bitness dynamically */
|
||||
break;
|
||||
if (type == IS_IA_EFI || type == IS_64_EFI || type == IS_ARM64_EFI ||
|
||||
type == IS_RISCV32_EFI || type == IS_RISCV64_EFI)
|
||||
{
|
||||
struct VasEBoot_pe64_optional_header o64;
|
||||
if (VasEBoot_file_read (file, &o64, sizeof (o64)) != sizeof (o64))
|
||||
break;
|
||||
if (o64.magic !=
|
||||
VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_PE64_MAGIC))
|
||||
break;
|
||||
if (o64.subsystem !=
|
||||
VasEBoot_cpu_to_le16_compile_time
|
||||
(VAS_EBOOT_PE32_SUBSYSTEM_EFI_APPLICATION))
|
||||
break;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
if (type == IS_32_EFI || type == IS_ARM_EFI)
|
||||
{
|
||||
struct VasEBoot_pe32_optional_header o32;
|
||||
if (VasEBoot_file_read (file, &o32, sizeof (o32)) != sizeof (o32))
|
||||
break;
|
||||
if (o32.magic !=
|
||||
VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PE32_PE32_MAGIC))
|
||||
break;
|
||||
if (o32.subsystem !=
|
||||
VasEBoot_cpu_to_le16_compile_time
|
||||
(VAS_EBOOT_PE32_SUBSYSTEM_EFI_APPLICATION))
|
||||
break;
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (elf)
|
||||
VasEBoot_elf_close (elf);
|
||||
else if (macho)
|
||||
VasEBoot_macho_close (macho);
|
||||
else if (file)
|
||||
VasEBoot_file_close (file);
|
||||
|
||||
if (!ret && (VasEBoot_errno == VAS_EBOOT_ERR_BAD_OS || VasEBoot_errno == VAS_EBOOT_ERR_NONE))
|
||||
/* TRANSLATORS: it's a standalone boolean value,
|
||||
opposite of "true". */
|
||||
VasEBoot_error (VAS_EBOOT_ERR_TEST_FAILURE, N_("false"));
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(file)
|
||||
{
|
||||
cmd = VasEBoot_register_extcmd ("file", VasEBoot_cmd_file, 0,
|
||||
N_("OPTIONS FILE"),
|
||||
N_("Check if FILE is of specified type."),
|
||||
options);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(file)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#define VAS_EBOOT_TARGET_WORDSIZE 32
|
||||
#define XX 32
|
||||
#define ehdrXX ehdr32
|
||||
#define VasEBoot_file_check_netbsdXX VasEBoot_file_check_netbsd32
|
||||
#include "fileXX.c"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#define VAS_EBOOT_TARGET_WORDSIZE 64
|
||||
#define XX 64
|
||||
#define ehdrXX ehdr64
|
||||
#define VasEBoot_file_check_netbsdXX VasEBoot_file_check_netbsd64
|
||||
#include "fileXX.c"
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/fileid.h>
|
||||
#include <VasEBoot/elfload.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
int
|
||||
VasEBoot_file_check_netbsdXX (VasEBoot_elf_t elf)
|
||||
{
|
||||
Elf_Shdr *s, *s0;
|
||||
|
||||
VasEBoot_size_t shnum = elf->ehdr.ehdrXX.e_shnum;
|
||||
VasEBoot_size_t shentsize = elf->ehdr.ehdrXX.e_shentsize;
|
||||
VasEBoot_size_t shsize = shnum * shentsize;
|
||||
VasEBoot_off_t stroff;
|
||||
|
||||
if (!shnum || !shentsize)
|
||||
return 0;
|
||||
|
||||
s0 = VasEBoot_malloc (shsize);
|
||||
if (!s0)
|
||||
return 0;
|
||||
|
||||
if (VasEBoot_file_seek (elf->file, elf->ehdr.ehdrXX.e_shoff) == (VasEBoot_off_t) -1)
|
||||
goto fail;
|
||||
|
||||
if (VasEBoot_file_read (elf->file, s0, shsize) != (VasEBoot_ssize_t) shsize)
|
||||
goto fail;
|
||||
|
||||
s = (Elf_Shdr *) ((char *) s0 + elf->ehdr.ehdrXX.e_shstrndx * shentsize);
|
||||
stroff = s->sh_offset;
|
||||
|
||||
for (s = s0; s < (Elf_Shdr *) ((char *) s0 + shnum * shentsize);
|
||||
s = (Elf_Shdr *) ((char *) s + shentsize))
|
||||
{
|
||||
char name[sizeof(".note.netbsd.ident")];
|
||||
VasEBoot_memset (name, 0, sizeof (name));
|
||||
if (VasEBoot_file_seek (elf->file, stroff + s->sh_name) == (VasEBoot_off_t) -1)
|
||||
goto fail;
|
||||
|
||||
if (VasEBoot_file_read (elf->file, name, sizeof (name)) != (VasEBoot_ssize_t) sizeof (name))
|
||||
{
|
||||
if (VasEBoot_errno)
|
||||
goto fail;
|
||||
continue;
|
||||
}
|
||||
if (VasEBoot_memcmp (name, ".note.netbsd.ident",
|
||||
sizeof(".note.netbsd.ident")) != 0)
|
||||
continue;
|
||||
VasEBoot_free (s0);
|
||||
return 1;
|
||||
}
|
||||
fail:
|
||||
VasEBoot_free (s0);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/* fwconfig.c - command to read config from qemu fwconfig */
|
||||
/*
|
||||
* VasEBoot -- GRand Unified Bootloader
|
||||
* Copyright (C) 2015 CoreOS, Inc.
|
||||
*
|
||||
* VasEBoot 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.
|
||||
*
|
||||
* VasEBoot 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 VasEBoot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/env.h>
|
||||
#include <VasEBoot/cpu/io.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
|
||||
VasEBoot_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define SELECTOR 0x510
|
||||
#define DATA 0x511
|
||||
|
||||
#define SIGNATURE_INDEX 0x00
|
||||
#define DIRECTORY_INDEX 0x19
|
||||
|
||||
static VasEBoot_extcmd_t cmd_read_fwconfig;
|
||||
|
||||
struct VasEBoot_qemu_fwcfgfile {
|
||||
VasEBoot_uint32_t size;
|
||||
VasEBoot_uint16_t select;
|
||||
VasEBoot_uint16_t reserved;
|
||||
char name[56];
|
||||
};
|
||||
|
||||
static const struct VasEBoot_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 VasEBoot_err_t
|
||||
VasEBoot_cmd_fwconfig (VasEBoot_extcmd_context_t ctxt __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
{
|
||||
VasEBoot_uint32_t i, j, value = 0;
|
||||
struct VasEBoot_qemu_fwcfgfile file;
|
||||
char fwsig[4], signature[4] = { 'Q', 'E', 'M', 'U' };
|
||||
|
||||
if (argc != 2)
|
||||
return VasEBoot_error (VasEBoot_ERR_BAD_ARGUMENT, N_("two arguments expected"));
|
||||
|
||||
/* Verify that we have meaningful hardware here */
|
||||
VasEBoot_outw(SIGNATURE_INDEX, SELECTOR);
|
||||
for (i=0; i<sizeof(fwsig); i++)
|
||||
fwsig[i] = VasEBoot_inb(DATA);
|
||||
|
||||
if (VasEBoot_memcmp(fwsig, signature, sizeof(signature)) != 0)
|
||||
return VasEBoot_error (VasEBoot_ERR_BAD_DEVICE, N_("invalid fwconfig hardware signature: got 0x%x%x%x%x"), fwsig[0], fwsig[1], fwsig[2], fwsig[3]);
|
||||
|
||||
/* Find out how many file entries we have */
|
||||
VasEBoot_outw(DIRECTORY_INDEX, SELECTOR);
|
||||
value = VasEBoot_inb(DATA) | VasEBoot_inb(DATA) << 8 | VasEBoot_inb(DATA) << 16 | VasEBoot_inb(DATA) << 24;
|
||||
value = VasEBoot_be_to_cpu32(value);
|
||||
/* Read the file description for each file */
|
||||
for (i=0; i<value; i++)
|
||||
{
|
||||
for (j=0; j<sizeof(file); j++)
|
||||
{
|
||||
((char *)&file)[j] = VasEBoot_inb(DATA);
|
||||
}
|
||||
/* Check whether it matches what we're looking for, and if so read the file */
|
||||
if (VasEBoot_strncmp(file.name, argv[0], sizeof(file.name)) == 0)
|
||||
{
|
||||
VasEBoot_uint32_t filesize = VasEBoot_be_to_cpu32(file.size);
|
||||
VasEBoot_uint16_t location = VasEBoot_be_to_cpu16(file.select);
|
||||
char *data = VasEBoot_malloc(filesize+1);
|
||||
|
||||
if (!data)
|
||||
return VasEBoot_error (VasEBoot_ERR_OUT_OF_MEMORY, N_("can't allocate buffer for data"));
|
||||
|
||||
VasEBoot_outw(location, SELECTOR);
|
||||
for (j=0; j<filesize; j++)
|
||||
{
|
||||
data[j] = VasEBoot_inb(DATA);
|
||||
}
|
||||
|
||||
data[filesize] = '\0';
|
||||
|
||||
VasEBoot_env_set (argv[1], data);
|
||||
|
||||
VasEBoot_free(data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return VasEBoot_error (VasEBoot_ERR_FILE_NOT_FOUND, N_("couldn't find entry %s"), argv[0]);
|
||||
}
|
||||
|
||||
VasEBoot_MOD_INIT(fwconfig)
|
||||
{
|
||||
cmd_read_fwconfig =
|
||||
VasEBoot_register_extcmd ("fwconfig", VasEBoot_cmd_fwconfig, 0,
|
||||
N_("PATH VAR"),
|
||||
N_("Set VAR to the contents of fwconfig PATH"),
|
||||
options);
|
||||
}
|
||||
|
||||
VasEBoot_MOD_FINI(fwconfig)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd_read_fwconfig);
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/* gptprio.c - manage priority based partition selection. */
|
||||
/*
|
||||
* VasEBoot -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2014 CoreOS, Inc.
|
||||
*
|
||||
* VasEBoot 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.
|
||||
*
|
||||
* VasEBoot 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 VasEBoot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/device.h>
|
||||
#include <VasEBoot/env.h>
|
||||
#include <VasEBoot/err.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/gpt_partition.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
|
||||
VasEBoot_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct VasEBoot_arg_option options_next[] = {
|
||||
{"set-device", 'd', 0,
|
||||
N_("Set a variable to the name of selected partition."),
|
||||
N_("VARNAME"), ARG_TYPE_STRING},
|
||||
{"set-uuid", 'u', 0,
|
||||
N_("Set a variable to the GPT UUID of selected partition."),
|
||||
N_("VARNAME"), ARG_TYPE_STRING},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
enum options_next
|
||||
{
|
||||
NEXT_SET_DEVICE,
|
||||
NEXT_SET_UUID,
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
VasEBoot_gptprio_priority (struct VasEBoot_gpt_partentry *entry)
|
||||
{
|
||||
return (unsigned int) VasEBoot_gpt_entry_attribute
|
||||
(entry, VasEBoot_GPT_PART_ATTR_OFFSET_GPTPRIO_PRIORITY, 4);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
VasEBoot_gptprio_tries_left (struct VasEBoot_gpt_partentry *entry)
|
||||
{
|
||||
return (unsigned int) VasEBoot_gpt_entry_attribute
|
||||
(entry, VasEBoot_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_gptprio_set_tries_left (struct VasEBoot_gpt_partentry *entry,
|
||||
unsigned int tries_left)
|
||||
{
|
||||
VasEBoot_gpt_entry_set_attribute
|
||||
(entry, tries_left, VasEBoot_GPT_PART_ATTR_OFFSET_GPTPRIO_TRIES_LEFT, 4);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
VasEBoot_gptprio_successful (struct VasEBoot_gpt_partentry *entry)
|
||||
{
|
||||
return (unsigned int) VasEBoot_gpt_entry_attribute
|
||||
(entry, VasEBoot_GPT_PART_ATTR_OFFSET_GPTPRIO_SUCCESSFUL, 1);
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_find_next (const char *disk_name,
|
||||
const VasEBoot_gpt_part_type_t *part_type,
|
||||
char **part_name, char **part_guid)
|
||||
{
|
||||
struct VasEBoot_gpt_partentry *part, *part_found = NULL;
|
||||
VasEBoot_device_t dev = NULL;
|
||||
VasEBoot_gpt_t gpt = NULL;
|
||||
VasEBoot_uint32_t i, part_index;
|
||||
|
||||
dev = VasEBoot_device_open (disk_name);
|
||||
if (!dev)
|
||||
goto done;
|
||||
|
||||
gpt = VasEBoot_gpt_read (dev->disk);
|
||||
if (!gpt)
|
||||
goto done;
|
||||
|
||||
if (VasEBoot_gpt_repair (dev->disk, gpt))
|
||||
goto done;
|
||||
|
||||
for (i = 0; (part = VasEBoot_gpt_get_partentry (gpt, i)) != NULL; i++)
|
||||
{
|
||||
if (VasEBoot_memcmp (part_type, &part->type, sizeof (*part_type)) == 0)
|
||||
{
|
||||
unsigned int priority, tries_left, successful, old_priority = 0;
|
||||
|
||||
priority = VasEBoot_gptprio_priority (part);
|
||||
tries_left = VasEBoot_gptprio_tries_left (part);
|
||||
successful = VasEBoot_gptprio_successful (part);
|
||||
|
||||
if (part_found)
|
||||
old_priority = VasEBoot_gptprio_priority (part_found);
|
||||
|
||||
if ((tries_left || successful) && priority > old_priority)
|
||||
{
|
||||
part_index = i;
|
||||
part_found = part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!part_found)
|
||||
{
|
||||
VasEBoot_error (VasEBoot_ERR_UNKNOWN_DEVICE, N_("no such partition"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (VasEBoot_gptprio_tries_left (part_found))
|
||||
{
|
||||
unsigned int tries_left = VasEBoot_gptprio_tries_left (part_found);
|
||||
|
||||
VasEBoot_gptprio_set_tries_left (part_found, tries_left - 1);
|
||||
|
||||
if (VasEBoot_gpt_update (gpt))
|
||||
goto done;
|
||||
|
||||
if (VasEBoot_gpt_write (dev->disk, gpt))
|
||||
goto done;
|
||||
}
|
||||
|
||||
*part_name = VasEBoot_xasprintf ("%s,gpt%u", disk_name, part_index + 1);
|
||||
if (!*part_name)
|
||||
goto done;
|
||||
|
||||
*part_guid = VasEBoot_gpt_guid_to_str (&part_found->guid);
|
||||
if (!*part_guid)
|
||||
goto done;
|
||||
|
||||
VasEBoot_errno = VasEBoot_ERR_NONE;
|
||||
|
||||
done:
|
||||
VasEBoot_gpt_free (gpt);
|
||||
|
||||
if (dev)
|
||||
VasEBoot_device_close (dev);
|
||||
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_next (VasEBoot_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct VasEBoot_arg_list *state = ctxt->state;
|
||||
char *p, *root = NULL, *part_name = NULL, *part_guid = NULL;
|
||||
|
||||
/* TODO: Add a uuid parser and a command line flag for providing type. */
|
||||
VasEBoot_gpt_part_type_t part_type = VasEBoot_GPT_PARTITION_TYPE_USR_X86_64;
|
||||
|
||||
if (!state[NEXT_SET_DEVICE].set || !state[NEXT_SET_UUID].set)
|
||||
{
|
||||
VasEBoot_error (VasEBoot_ERR_INVALID_COMMAND, N_("-d and -u are required"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (argc == 0)
|
||||
root = VasEBoot_strdup (VasEBoot_env_get ("root"));
|
||||
else if (argc == 1)
|
||||
root = VasEBoot_strdup (args[0]);
|
||||
else
|
||||
{
|
||||
VasEBoot_error (VasEBoot_ERR_BAD_ARGUMENT, N_("unexpected arguments"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!root)
|
||||
goto done;
|
||||
|
||||
/* To make using $root practical strip off the partition name. */
|
||||
p = VasEBoot_strchr (root, ',');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
|
||||
if (VasEBoot_find_next (root, &part_type, &part_name, &part_guid))
|
||||
goto done;
|
||||
|
||||
if (VasEBoot_env_set (state[NEXT_SET_DEVICE].arg, part_name))
|
||||
goto done;
|
||||
|
||||
if (VasEBoot_env_set (state[NEXT_SET_UUID].arg, part_guid))
|
||||
goto done;
|
||||
|
||||
VasEBoot_errno = VasEBoot_ERR_NONE;
|
||||
|
||||
done:
|
||||
VasEBoot_free (root);
|
||||
VasEBoot_free (part_name);
|
||||
VasEBoot_free (part_guid);
|
||||
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd_next;
|
||||
|
||||
VasEBoot_MOD_INIT(gptprio)
|
||||
{
|
||||
cmd_next = VasEBoot_register_extcmd ("gptprio.next", VasEBoot_cmd_next, 0,
|
||||
N_("-d VARNAME -u VARNAME [DEVICE]"),
|
||||
N_("Select next partition to boot."),
|
||||
options_next);
|
||||
}
|
||||
|
||||
VasEBoot_MOD_FINI(gptprio)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd_next);
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/* gptrepair.c - verify and restore GPT info from alternate location. */
|
||||
/*
|
||||
* VasEBoot -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2014 CoreOS, Inc.
|
||||
*
|
||||
* VasEBoot 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.
|
||||
*
|
||||
* VasEBoot 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 VasEBoot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/device.h>
|
||||
#include <VasEBoot/err.h>
|
||||
#include <VasEBoot/gpt_partition.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
|
||||
VasEBoot_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static char *
|
||||
trim_dev_name (char *name)
|
||||
{
|
||||
VasEBoot_size_t len = VasEBoot_strlen (name);
|
||||
if (len && name[0] == '(' && name[len - 1] == ')')
|
||||
{
|
||||
name[len - 1] = '\0';
|
||||
name = name + 1;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_gptrepair (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
VasEBoot_device_t dev = NULL;
|
||||
VasEBoot_gpt_t gpt = NULL;
|
||||
char *dev_name;
|
||||
|
||||
if (argc != 1 || !VasEBoot_strlen(args[0]))
|
||||
return VasEBoot_error (VasEBoot_ERR_BAD_ARGUMENT, "device name required");
|
||||
|
||||
dev_name = trim_dev_name (args[0]);
|
||||
dev = VasEBoot_device_open (dev_name);
|
||||
if (!dev)
|
||||
goto done;
|
||||
|
||||
if (!dev->disk)
|
||||
{
|
||||
VasEBoot_error (VasEBoot_ERR_BAD_ARGUMENT, "not a disk");
|
||||
goto done;
|
||||
}
|
||||
|
||||
gpt = VasEBoot_gpt_read (dev->disk);
|
||||
if (!gpt)
|
||||
goto done;
|
||||
|
||||
if (VasEBoot_gpt_both_valid (gpt))
|
||||
{
|
||||
VasEBoot_printf_ (N_("GPT already valid, %s unmodified.\n"), dev_name);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!VasEBoot_gpt_primary_valid (gpt))
|
||||
VasEBoot_printf_ (N_("Found invalid primary GPT on %s\n"), dev_name);
|
||||
|
||||
if (!VasEBoot_gpt_backup_valid (gpt))
|
||||
VasEBoot_printf_ (N_("Found invalid backup GPT on %s\n"), dev_name);
|
||||
|
||||
if (VasEBoot_gpt_repair (dev->disk, gpt))
|
||||
goto done;
|
||||
|
||||
if (VasEBoot_gpt_write (dev->disk, gpt))
|
||||
goto done;
|
||||
|
||||
VasEBoot_printf_ (N_("Repaired GPT on %s\n"), dev_name);
|
||||
|
||||
done:
|
||||
if (gpt)
|
||||
VasEBoot_gpt_free (gpt);
|
||||
|
||||
if (dev)
|
||||
VasEBoot_device_close (dev);
|
||||
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VasEBoot_MOD_INIT(gptrepair)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("gptrepair", VasEBoot_cmd_gptrepair,
|
||||
N_("DEVICE"),
|
||||
N_("Verify and repair GPT on drive DEVICE."));
|
||||
}
|
||||
|
||||
VasEBoot_MOD_FINI(gptrepair)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
/* gptsync.c - fill the mbr based on gpt entries */
|
||||
/* XXX: I don't know what to do if sector size isn't 512 bytes */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/device.h>
|
||||
#include <VasEBoot/disk.h>
|
||||
#include <VasEBoot/msdos_partition.h>
|
||||
#include <VasEBoot/partition.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/fs.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
/* Convert a LBA address to a CHS address in the INT 13 format. */
|
||||
/* Taken from VasEBoot1. */
|
||||
/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
|
||||
Is it a problem?
|
||||
*/
|
||||
static void
|
||||
lba_to_chs (VasEBoot_uint32_t lba, VasEBoot_uint8_t *cl, VasEBoot_uint8_t *ch,
|
||||
VasEBoot_uint8_t *dh)
|
||||
{
|
||||
VasEBoot_uint32_t cylinder, head, sector;
|
||||
VasEBoot_uint32_t sectors = 63, heads = 255, cylinders = 1024;
|
||||
|
||||
sector = lba % sectors + 1;
|
||||
head = (lba / sectors) % heads;
|
||||
cylinder = lba / (sectors * heads);
|
||||
|
||||
if (cylinder >= cylinders)
|
||||
{
|
||||
*cl = *ch = *dh = 0xff;
|
||||
return;
|
||||
}
|
||||
|
||||
*cl = sector | ((cylinder & 0x300) >> 2);
|
||||
*ch = cylinder & 0xFF;
|
||||
*dh = head;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_gptsync (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
VasEBoot_device_t dev;
|
||||
struct VasEBoot_msdos_partition_mbr mbr;
|
||||
struct VasEBoot_partition *partition;
|
||||
VasEBoot_disk_addr_t first_sector;
|
||||
int numactive = 0;
|
||||
int i;
|
||||
|
||||
if (argc < 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "device name required");
|
||||
if (argc > 4)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "only 3 partitions can be "
|
||||
"in hybrid MBR");
|
||||
|
||||
if (args[0][0] == '(' && args[0][VasEBoot_strlen (args[0]) - 1] == ')')
|
||||
{
|
||||
args[0][VasEBoot_strlen (args[0]) - 1] = 0;
|
||||
dev = VasEBoot_device_open (args[0] + 1);
|
||||
args[0][VasEBoot_strlen (args[0])] = ')';
|
||||
}
|
||||
else
|
||||
dev = VasEBoot_device_open (args[0]);
|
||||
|
||||
if (! dev)
|
||||
return VasEBoot_errno;
|
||||
|
||||
if (! dev->disk)
|
||||
{
|
||||
VasEBoot_device_close (dev);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "not a disk");
|
||||
}
|
||||
|
||||
/* Read the protective MBR. */
|
||||
if (VasEBoot_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
|
||||
{
|
||||
VasEBoot_device_close (dev);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
/* Check if it is valid. */
|
||||
if (mbr.signature != VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PC_PARTITION_SIGNATURE))
|
||||
{
|
||||
VasEBoot_device_close (dev);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_PART_TABLE, "no signature");
|
||||
}
|
||||
|
||||
/* Make sure the MBR is a protective MBR and not a normal MBR. */
|
||||
for (i = 0; i < 4; i++)
|
||||
if (mbr.entries[i].type == VAS_EBOOT_PC_PARTITION_TYPE_GPT_DISK)
|
||||
break;
|
||||
if (i == 4)
|
||||
{
|
||||
VasEBoot_device_close (dev);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_PART_TABLE, "no GPT partition map found");
|
||||
}
|
||||
|
||||
first_sector = dev->disk->total_sectors;
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
char *separator, csep = 0;
|
||||
VasEBoot_uint8_t type;
|
||||
separator = VasEBoot_strchr (args[i], '+');
|
||||
if (! separator)
|
||||
separator = VasEBoot_strchr (args[i], '-');
|
||||
if (separator)
|
||||
{
|
||||
csep = *separator;
|
||||
*separator = 0;
|
||||
}
|
||||
partition = VasEBoot_partition_probe (dev->disk, args[i]);
|
||||
if (separator)
|
||||
*separator = csep;
|
||||
if (! partition)
|
||||
{
|
||||
VasEBoot_device_close (dev);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_UNKNOWN_DEVICE,
|
||||
N_("no such partition"));
|
||||
}
|
||||
|
||||
if (partition->start + partition->len > 0xffffffff)
|
||||
{
|
||||
VasEBoot_device_close (dev);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_RANGE,
|
||||
"only partitions residing in the first 2TB "
|
||||
"can be present in hybrid MBR");
|
||||
}
|
||||
|
||||
|
||||
if (first_sector > partition->start)
|
||||
first_sector = partition->start;
|
||||
|
||||
if (separator && *(separator + 1))
|
||||
type = VasEBoot_strtoul (separator + 1, 0, 0);
|
||||
else
|
||||
{
|
||||
VasEBoot_fs_t fs = 0;
|
||||
dev->disk->partition = partition;
|
||||
fs = VasEBoot_fs_probe (dev);
|
||||
|
||||
/* Unknown filesystem isn't fatal. */
|
||||
if (VasEBoot_errno == VAS_EBOOT_ERR_UNKNOWN_FS)
|
||||
{
|
||||
fs = 0;
|
||||
VasEBoot_errno = VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
if (fs && VasEBoot_strcmp (fs->name, "ntfs") == 0)
|
||||
type = VAS_EBOOT_PC_PARTITION_TYPE_NTFS;
|
||||
else if (fs && VasEBoot_strcmp (fs->name, "fat") == 0)
|
||||
/* FIXME: detect FAT16. */
|
||||
type = VAS_EBOOT_PC_PARTITION_TYPE_FAT32_LBA;
|
||||
else if (fs && (VasEBoot_strcmp (fs->name, "hfsplus") == 0
|
||||
|| VasEBoot_strcmp (fs->name, "hfs") == 0))
|
||||
type = VAS_EBOOT_PC_PARTITION_TYPE_HFS;
|
||||
else
|
||||
/* FIXME: detect more types. */
|
||||
type = VAS_EBOOT_PC_PARTITION_TYPE_EXT2FS;
|
||||
|
||||
dev->disk->partition = 0;
|
||||
}
|
||||
|
||||
mbr.entries[i].flag = (csep == '+') ? 0x80 : 0;
|
||||
if (csep == '+')
|
||||
{
|
||||
numactive++;
|
||||
if (numactive == 2)
|
||||
{
|
||||
VasEBoot_device_close (dev);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
"only one partition can be active");
|
||||
}
|
||||
}
|
||||
mbr.entries[i].type = type;
|
||||
mbr.entries[i].start = VasEBoot_cpu_to_le32 (partition->start);
|
||||
lba_to_chs (partition->start,
|
||||
&(mbr.entries[i].start_sector),
|
||||
&(mbr.entries[i].start_cylinder),
|
||||
&(mbr.entries[i].start_head));
|
||||
lba_to_chs (partition->start + partition->len - 1,
|
||||
&(mbr.entries[i].end_sector),
|
||||
&(mbr.entries[i].end_cylinder),
|
||||
&(mbr.entries[i].end_head));
|
||||
mbr.entries[i].length = VasEBoot_cpu_to_le32 (partition->len);
|
||||
VasEBoot_free (partition);
|
||||
}
|
||||
for (; i < 4; i++)
|
||||
VasEBoot_memset (&(mbr.entries[i]), 0, sizeof (mbr.entries[i]));
|
||||
|
||||
/* The protective partition. */
|
||||
if (first_sector > 0xffffffff)
|
||||
first_sector = 0xffffffff;
|
||||
else
|
||||
first_sector--;
|
||||
mbr.entries[0].flag = 0;
|
||||
mbr.entries[0].type = VAS_EBOOT_PC_PARTITION_TYPE_GPT_DISK;
|
||||
mbr.entries[0].start = VasEBoot_cpu_to_le32_compile_time (1);
|
||||
lba_to_chs (1,
|
||||
&(mbr.entries[0].start_sector),
|
||||
&(mbr.entries[0].start_cylinder),
|
||||
&(mbr.entries[0].start_head));
|
||||
lba_to_chs (first_sector,
|
||||
&(mbr.entries[0].end_sector),
|
||||
&(mbr.entries[0].end_cylinder),
|
||||
&(mbr.entries[0].end_head));
|
||||
mbr.entries[0].length = VasEBoot_cpu_to_le32 (first_sector);
|
||||
|
||||
mbr.signature = VasEBoot_cpu_to_le16_compile_time (VAS_EBOOT_PC_PARTITION_SIGNATURE);
|
||||
|
||||
if (VasEBoot_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr))
|
||||
{
|
||||
VasEBoot_device_close (dev);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
VasEBoot_device_close (dev);
|
||||
|
||||
VasEBoot_printf_ (N_("New MBR is written to `%s'\n"), args[0]);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(gptsync)
|
||||
{
|
||||
(void) mod; /* To stop warning. */
|
||||
cmd = VasEBoot_register_command ("gptsync", VasEBoot_cmd_gptsync,
|
||||
N_("DEVICE [PARTITION[+/-[TYPE]]] ..."),
|
||||
/* TRANSLATORS: MBR type is one-byte partition
|
||||
type id. */
|
||||
N_("Fill hybrid MBR of GPT drive DEVICE. "
|
||||
"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."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(gptsync)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* halt.c - command to halt the computer. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007,2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/command.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_err_t __attribute__ ((noreturn))
|
||||
VasEBoot_cmd_halt (VasEBoot_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
VasEBoot_halt ();
|
||||
}
|
||||
|
||||
static VasEBoot_command_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(halt)
|
||||
{
|
||||
cmd = VasEBoot_register_command ("halt", VasEBoot_cmd_halt,
|
||||
0, N_("Halts the computer. This command does"
|
||||
" not work on all firmware implementations."));
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(halt)
|
||||
{
|
||||
VasEBoot_unregister_command (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/file.h>
|
||||
#include <VasEBoot/disk.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/crypto.h>
|
||||
#include <VasEBoot/normal.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct VasEBoot_arg_option options[] = {
|
||||
{"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING},
|
||||
{"check", 'c', 0, N_("Check hashes of files with hash list FILE."),
|
||||
N_("FILE"), ARG_TYPE_STRING},
|
||||
{"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIR"),
|
||||
ARG_TYPE_STRING},
|
||||
{"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0},
|
||||
{"uncompress", 'u', 0, N_("Uncompress file before checksumming."), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct { const char *name; const char *hashname; } aliases[] =
|
||||
{
|
||||
{"sha256sum", "sha256"},
|
||||
{"sha512sum", "sha512"},
|
||||
{"sha1sum", "sha1"},
|
||||
{"md5sum", "md5"},
|
||||
{"crc", "crc32"},
|
||||
};
|
||||
|
||||
static inline int
|
||||
hextoval (char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
hash_file (VasEBoot_file_t file, const gcry_md_spec_t *hash, void *result)
|
||||
{
|
||||
void *context;
|
||||
VasEBoot_uint8_t *readbuf;
|
||||
#define BUF_SIZE 4096
|
||||
readbuf = VasEBoot_malloc (BUF_SIZE);
|
||||
if (!readbuf)
|
||||
return VasEBoot_errno;
|
||||
context = VasEBoot_zalloc (hash->contextsize);
|
||||
if (!readbuf || !context)
|
||||
goto fail;
|
||||
|
||||
hash->init (context, 0);
|
||||
while (1)
|
||||
{
|
||||
VasEBoot_ssize_t r;
|
||||
r = VasEBoot_file_read (file, readbuf, BUF_SIZE);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
if (r == 0)
|
||||
break;
|
||||
hash->write (context, readbuf, r);
|
||||
}
|
||||
hash->final (context);
|
||||
VasEBoot_memcpy (result, hash->read (context), hash->mdlen);
|
||||
|
||||
VasEBoot_free (readbuf);
|
||||
VasEBoot_free (context);
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
|
||||
fail:
|
||||
VasEBoot_free (readbuf);
|
||||
VasEBoot_free (context);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||
const char *prefix, int keep, int uncompress)
|
||||
{
|
||||
VasEBoot_file_t hashlist, file;
|
||||
char *buf = NULL;
|
||||
VasEBoot_uint8_t expected[VAS_EBOOT_CRYPTO_MAX_MDLEN];
|
||||
VasEBoot_uint8_t actual[VAS_EBOOT_CRYPTO_MAX_MDLEN];
|
||||
VasEBoot_err_t err;
|
||||
unsigned i;
|
||||
unsigned unread = 0, mismatch = 0;
|
||||
|
||||
if (hash->mdlen > VAS_EBOOT_CRYPTO_MAX_MDLEN)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BUG, "mdlen is too long");
|
||||
|
||||
hashlist = VasEBoot_file_open (hashfilename, VAS_EBOOT_FILE_TYPE_HASHLIST);
|
||||
if (!hashlist)
|
||||
return VasEBoot_errno;
|
||||
|
||||
while (VasEBoot_free (buf), (buf = VasEBoot_file_getline (hashlist)))
|
||||
{
|
||||
const char *p = buf;
|
||||
while (VasEBoot_isspace (p[0]))
|
||||
p++;
|
||||
for (i = 0; i < hash->mdlen; i++)
|
||||
{
|
||||
int high, low;
|
||||
high = hextoval (*p++);
|
||||
low = hextoval (*p++);
|
||||
if (high < 0 || low < 0)
|
||||
{
|
||||
VasEBoot_free (buf);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "invalid hash list");
|
||||
}
|
||||
expected[i] = (high << 4) | low;
|
||||
}
|
||||
if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t'))
|
||||
{
|
||||
VasEBoot_free (buf);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_FILE_TYPE, "invalid hash list");
|
||||
}
|
||||
p += 2;
|
||||
if (prefix)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
filename = VasEBoot_xasprintf ("%s/%s", prefix, p);
|
||||
if (!filename)
|
||||
{
|
||||
VasEBoot_free (buf);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
file = VasEBoot_file_open (filename, VAS_EBOOT_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? VAS_EBOOT_FILE_TYPE_NO_DECOMPRESS
|
||||
: VAS_EBOOT_FILE_TYPE_NONE));
|
||||
VasEBoot_free (filename);
|
||||
}
|
||||
else
|
||||
file = VasEBoot_file_open (p, VAS_EBOOT_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? VAS_EBOOT_FILE_TYPE_NO_DECOMPRESS
|
||||
: VAS_EBOOT_FILE_TYPE_NONE));
|
||||
if (!file)
|
||||
{
|
||||
VasEBoot_file_close (hashlist);
|
||||
VasEBoot_free (buf);
|
||||
return VasEBoot_errno;
|
||||
}
|
||||
err = hash_file (file, hash, actual);
|
||||
VasEBoot_file_close (file);
|
||||
if (err)
|
||||
{
|
||||
VasEBoot_printf_ (N_("%s: READ ERROR\n"), p);
|
||||
if (!keep)
|
||||
{
|
||||
VasEBoot_file_close (hashlist);
|
||||
VasEBoot_free (buf);
|
||||
return err;
|
||||
}
|
||||
VasEBoot_print_error ();
|
||||
VasEBoot_errno = VAS_EBOOT_ERR_NONE;
|
||||
unread++;
|
||||
continue;
|
||||
}
|
||||
if (VasEBoot_crypto_memcmp (expected, actual, hash->mdlen) != 0)
|
||||
{
|
||||
VasEBoot_printf_ (N_("%s: HASH MISMATCH\n"), p);
|
||||
if (!keep)
|
||||
{
|
||||
VasEBoot_file_close (hashlist);
|
||||
VasEBoot_free (buf);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_TEST_FAILURE,
|
||||
"hash of '%s' mismatches", p);
|
||||
}
|
||||
mismatch++;
|
||||
continue;
|
||||
}
|
||||
VasEBoot_printf_ (N_("%s: OK\n"), p);
|
||||
}
|
||||
if (mismatch || unread)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_TEST_FAILURE,
|
||||
"%d files couldn't be read and hash "
|
||||
"of %d files mismatches", unread, mismatch);
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_hashsum (struct VasEBoot_extcmd_context *ctxt,
|
||||
int argc, char **args)
|
||||
{
|
||||
struct VasEBoot_arg_list *state = ctxt->state;
|
||||
const char *hashname = NULL;
|
||||
const char *prefix = NULL;
|
||||
const gcry_md_spec_t *hash;
|
||||
unsigned i;
|
||||
int keep = state[3].set;
|
||||
int uncompress = state[4].set;
|
||||
unsigned unread = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (aliases); i++)
|
||||
if (VasEBoot_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0)
|
||||
hashname = aliases[i].hashname;
|
||||
if (state[0].set)
|
||||
hashname = state[0].arg;
|
||||
|
||||
if (!hashname)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "no hash specified");
|
||||
|
||||
hash = VasEBoot_crypto_lookup_md_by_name (hashname);
|
||||
if (!hash)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, "unknown hash");
|
||||
|
||||
if (hash->mdlen > VAS_EBOOT_CRYPTO_MAX_MDLEN)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BUG, "mdlen is too long");
|
||||
|
||||
if (state[2].set)
|
||||
prefix = state[2].arg;
|
||||
|
||||
if (state[1].set)
|
||||
{
|
||||
if (argc != 0)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT,
|
||||
"--check is incompatible with file list");
|
||||
return check_list (hash, state[1].arg, prefix, keep, uncompress);
|
||||
}
|
||||
|
||||
for (i = 0; i < (unsigned) argc; i++)
|
||||
{
|
||||
VAS_EBOOT_PROPERLY_ALIGNED_ARRAY (result, VAS_EBOOT_CRYPTO_MAX_MDLEN);
|
||||
VasEBoot_file_t file;
|
||||
VasEBoot_err_t err;
|
||||
unsigned j;
|
||||
file = VasEBoot_file_open (args[i], VAS_EBOOT_FILE_TYPE_TO_HASH
|
||||
| (!uncompress ? VAS_EBOOT_FILE_TYPE_NO_DECOMPRESS
|
||||
: VAS_EBOOT_FILE_TYPE_NONE));
|
||||
if (!file)
|
||||
{
|
||||
if (!keep)
|
||||
return VasEBoot_errno;
|
||||
VasEBoot_print_error ();
|
||||
VasEBoot_errno = VAS_EBOOT_ERR_NONE;
|
||||
unread++;
|
||||
continue;
|
||||
}
|
||||
err = hash_file (file, hash, result);
|
||||
VasEBoot_file_close (file);
|
||||
if (err)
|
||||
{
|
||||
if (!keep)
|
||||
return err;
|
||||
VasEBoot_print_error ();
|
||||
VasEBoot_errno = VAS_EBOOT_ERR_NONE;
|
||||
unread++;
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < hash->mdlen; j++)
|
||||
VasEBoot_printf ("%02x", ((VasEBoot_uint8_t *) result)[j]);
|
||||
VasEBoot_printf (" %s\n", args[i]);
|
||||
}
|
||||
|
||||
if (unread)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_TEST_FAILURE, "%d files couldn't be read",
|
||||
unread);
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(hashsum)
|
||||
{
|
||||
cmd = VasEBoot_register_extcmd ("hashsum", VasEBoot_cmd_hashsum, 0,
|
||||
N_("-h HASH [-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
/* TRANSLATORS: "hash checksum" is just to
|
||||
be a bit more precise, you can treat it as
|
||||
just "hash". */
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_md5 = VasEBoot_register_extcmd ("md5sum", VasEBoot_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha1 = VasEBoot_register_extcmd ("sha1sum", VasEBoot_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha256 = VasEBoot_register_extcmd ("sha256sum", VasEBoot_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha512 = VasEBoot_register_extcmd ("sha512sum", VasEBoot_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
|
||||
cmd_crc = VasEBoot_register_extcmd ("crc", VasEBoot_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(hashsum)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd);
|
||||
VasEBoot_unregister_extcmd (cmd_md5);
|
||||
VasEBoot_unregister_extcmd (cmd_sha1);
|
||||
VasEBoot_unregister_extcmd (cmd_sha256);
|
||||
VasEBoot_unregister_extcmd (cmd_sha512);
|
||||
VasEBoot_unregister_extcmd (cmd_crc);
|
||||
}
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
/* hdparm.c - command to get/set ATA disk parameters. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/ata.h>
|
||||
#include <VasEBoot/scsi.h>
|
||||
#include <VasEBoot/disk.h>
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/lib/hexdump.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static const struct VasEBoot_arg_option options[] = {
|
||||
{"apm", 'B', 0, N_("Set Advanced Power Management\n"
|
||||
"(1=low, ..., 254=high, 255=off)."),
|
||||
0, ARG_TYPE_INT},
|
||||
{"power", 'C', 0, N_("Display power mode."), 0, ARG_TYPE_NONE},
|
||||
{"security-freeze", 'F', 0, N_("Freeze ATA security settings until reset."),
|
||||
0, ARG_TYPE_NONE},
|
||||
{"health", 'H', 0, N_("Display SMART health status."), 0, ARG_TYPE_NONE},
|
||||
{"aam", 'M', 0, N_("Set Automatic Acoustic Management\n"
|
||||
"(0=off, 128=quiet, ..., 254=fast)."),
|
||||
0, ARG_TYPE_INT},
|
||||
{"standby-timeout", 'S', 0, N_("Set standby timeout\n"
|
||||
"(0=off, 1=5s, 2=10s, ..., 240=20m, 241=30m, ...)."),
|
||||
0, ARG_TYPE_INT},
|
||||
{"standby", 'y', 0, N_("Set drive to standby mode."), 0, ARG_TYPE_NONE},
|
||||
{"sleep", 'Y', 0, N_("Set drive to sleep mode."), 0, ARG_TYPE_NONE},
|
||||
{"identify", 'i', 0, N_("Print drive identity and settings."),
|
||||
0, ARG_TYPE_NONE},
|
||||
{"dumpid", 'I', 0, N_("Show raw contents of ATA IDENTIFY sector."),
|
||||
0, ARG_TYPE_NONE},
|
||||
{"smart", -1, 0, N_("Disable/enable SMART (0/1)."), 0, ARG_TYPE_INT},
|
||||
{"quiet", 'q', 0, N_("Do not print messages."), 0, ARG_TYPE_NONE},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
enum VasEBoot_ata_smart_commands
|
||||
{
|
||||
VAS_EBOOT_ATA_FEAT_SMART_ENABLE = 0xd8,
|
||||
VAS_EBOOT_ATA_FEAT_SMART_DISABLE = 0xd9,
|
||||
VAS_EBOOT_ATA_FEAT_SMART_STATUS = 0xda,
|
||||
};
|
||||
|
||||
static int quiet = 0;
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_hdparm_do_ata_cmd (VasEBoot_ata_t ata, VasEBoot_uint8_t cmd,
|
||||
VasEBoot_uint8_t features, VasEBoot_uint8_t sectors,
|
||||
void * buffer, int size)
|
||||
{
|
||||
struct VasEBoot_disk_ata_pass_through_parms apt;
|
||||
VasEBoot_memset (&apt, 0, sizeof (apt));
|
||||
|
||||
apt.taskfile.cmd = cmd;
|
||||
apt.taskfile.features = features;
|
||||
apt.taskfile.sectors = sectors;
|
||||
apt.taskfile.disk = 0xE0;
|
||||
|
||||
apt.buffer = buffer;
|
||||
apt.size = size;
|
||||
|
||||
if (ata->dev->readwrite (ata, &apt, 0))
|
||||
return VasEBoot_errno;
|
||||
|
||||
return VAS_EBOOT_ERR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
VasEBoot_hdparm_do_check_powermode_cmd (VasEBoot_ata_t ata)
|
||||
{
|
||||
struct VasEBoot_disk_ata_pass_through_parms apt;
|
||||
VasEBoot_memset (&apt, 0, sizeof (apt));
|
||||
|
||||
apt.taskfile.cmd = VAS_EBOOT_ATA_CMD_CHECK_POWER_MODE;
|
||||
apt.taskfile.disk = 0xE0;
|
||||
|
||||
if (ata->dev->readwrite (ata, &apt, 0))
|
||||
return -1;
|
||||
|
||||
return apt.taskfile.sectors;
|
||||
}
|
||||
|
||||
static int
|
||||
VasEBoot_hdparm_do_smart_cmd (VasEBoot_ata_t ata, VasEBoot_uint8_t features)
|
||||
{
|
||||
struct VasEBoot_disk_ata_pass_through_parms apt;
|
||||
VasEBoot_memset (&apt, 0, sizeof (apt));
|
||||
|
||||
apt.taskfile.cmd = VAS_EBOOT_ATA_CMD_SMART;
|
||||
apt.taskfile.features = features;
|
||||
apt.taskfile.lba_mid = 0x4f;
|
||||
apt.taskfile.lba_high = 0xc2;
|
||||
apt.taskfile.disk = 0xE0;
|
||||
|
||||
if (ata->dev->readwrite (ata, &apt, 0))
|
||||
return -1;
|
||||
|
||||
if (features == VAS_EBOOT_ATA_FEAT_SMART_STATUS)
|
||||
{
|
||||
if ( apt.taskfile.lba_mid == 0x4f
|
||||
&& apt.taskfile.lba_high == 0xc2)
|
||||
return 0; /* Good SMART status. */
|
||||
else if ( apt.taskfile.lba_mid == 0xf4
|
||||
&& apt.taskfile.lba_high == 0x2c)
|
||||
return 1; /* Bad SMART status. */
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_hdparm_simple_cmd (const char * msg,
|
||||
VasEBoot_ata_t ata, VasEBoot_uint8_t cmd)
|
||||
{
|
||||
if (! quiet && msg)
|
||||
VasEBoot_printf ("%s", msg);
|
||||
|
||||
VasEBoot_err_t err = VasEBoot_hdparm_do_ata_cmd (ata, cmd, 0, 0, NULL, 0);
|
||||
|
||||
if (! quiet && msg)
|
||||
VasEBoot_printf ("%s\n", ! err ? "" : ": not supported");
|
||||
return err;
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_hdparm_set_val_cmd (const char * msg, int val,
|
||||
VasEBoot_ata_t ata, VasEBoot_uint8_t cmd,
|
||||
VasEBoot_uint8_t features, VasEBoot_uint8_t sectors)
|
||||
{
|
||||
if (! quiet && msg && *msg)
|
||||
{
|
||||
if (val >= 0)
|
||||
VasEBoot_printf ("Set %s to %d", msg, val);
|
||||
else
|
||||
VasEBoot_printf ("Disable %s", msg);
|
||||
}
|
||||
|
||||
VasEBoot_err_t err = VasEBoot_hdparm_do_ata_cmd (ata, cmd, features, sectors,
|
||||
NULL, 0);
|
||||
|
||||
if (! quiet && msg)
|
||||
VasEBoot_printf ("%s\n", ! err ? "" : ": not supported");
|
||||
return err;
|
||||
}
|
||||
|
||||
static const char *
|
||||
le16_to_char (VasEBoot_uint16_t *dest, const VasEBoot_uint16_t * src16, unsigned bytes)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < bytes / 2; i++)
|
||||
dest[i] = VasEBoot_swap_bytes16 (src16[i]);
|
||||
dest[i] = 0;
|
||||
return (char *) dest;
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_hdparm_print_identify (const VasEBoot_uint16_t * idw)
|
||||
{
|
||||
/* Print identity strings. */
|
||||
VasEBoot_uint16_t tmp[21];
|
||||
VasEBoot_printf ("Model: \"%.40s\"\n", le16_to_char (tmp, &idw[27], 40));
|
||||
VasEBoot_printf ("Firmware: \"%.8s\"\n", le16_to_char (tmp, &idw[23], 8));
|
||||
VasEBoot_printf ("Serial: \"%.20s\"\n", le16_to_char (tmp, &idw[10], 20));
|
||||
|
||||
/* Print AAM, APM and SMART settings. */
|
||||
VasEBoot_uint16_t features1 = VasEBoot_le_to_cpu16 (idw[82]);
|
||||
VasEBoot_uint16_t features2 = VasEBoot_le_to_cpu16 (idw[83]);
|
||||
VasEBoot_uint16_t enabled1 = VasEBoot_le_to_cpu16 (idw[85]);
|
||||
VasEBoot_uint16_t enabled2 = VasEBoot_le_to_cpu16 (idw[86]);
|
||||
|
||||
VasEBoot_printf ("Automatic Acoustic Management: ");
|
||||
if (features2 & 0x0200)
|
||||
{
|
||||
if (enabled2 & 0x0200)
|
||||
{
|
||||
VasEBoot_uint16_t aam = VasEBoot_le_to_cpu16 (idw[94]);
|
||||
VasEBoot_printf ("%u (128=quiet, ..., 254=fast, recommended=%u)\n",
|
||||
aam & 0xff, (aam >> 8) & 0xff);
|
||||
}
|
||||
else
|
||||
VasEBoot_printf ("disabled\n");
|
||||
}
|
||||
else
|
||||
VasEBoot_printf ("not supported\n");
|
||||
|
||||
VasEBoot_printf ("Advanced Power Management: ");
|
||||
if (features2 & 0x0008)
|
||||
{
|
||||
if (enabled2 & 0x0008)
|
||||
VasEBoot_printf ("%u (1=low, ..., 254=high)\n",
|
||||
VasEBoot_le_to_cpu16 (idw[91]) & 0xff);
|
||||
else
|
||||
VasEBoot_printf ("disabled\n");
|
||||
}
|
||||
else
|
||||
VasEBoot_printf ("not supported\n");
|
||||
|
||||
VasEBoot_printf ("SMART Feature Set: ");
|
||||
if (features1 & 0x0001)
|
||||
VasEBoot_printf ("%sabled\n", (enabled1 & 0x0001 ? "en" : "dis"));
|
||||
else
|
||||
VasEBoot_printf ("not supported\n");
|
||||
|
||||
/* Print security settings. */
|
||||
VasEBoot_uint16_t security = VasEBoot_le_to_cpu16 (idw[128]);
|
||||
|
||||
VasEBoot_printf ("ATA Security: ");
|
||||
if (security & 0x0001)
|
||||
VasEBoot_printf ("%s, %s, %s, %s\n",
|
||||
(security & 0x0002 ? "ENABLED" : "disabled"),
|
||||
(security & 0x0004 ? "**LOCKED**" : "not locked"),
|
||||
(security & 0x0008 ? "frozen" : "NOT FROZEN"),
|
||||
(security & 0x0010 ? "COUNT EXPIRED" : "count not expired"));
|
||||
else
|
||||
VasEBoot_printf ("not supported\n");
|
||||
}
|
||||
|
||||
static void
|
||||
VasEBoot_hdparm_print_standby_tout (int timeout)
|
||||
{
|
||||
if (timeout == 0)
|
||||
VasEBoot_printf ("off");
|
||||
else if (timeout <= 252 || timeout == 255)
|
||||
{
|
||||
int h = 0, m = 0 , s = 0;
|
||||
if (timeout == 255)
|
||||
{
|
||||
m = 21;
|
||||
s = 15;
|
||||
}
|
||||
else if (timeout == 252)
|
||||
m = 21;
|
||||
else if (timeout <= 240)
|
||||
{
|
||||
s = timeout * 5;
|
||||
m = s / 60;
|
||||
s %= 60;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = (timeout - 240) * 30;
|
||||
h = m / 60;
|
||||
m %= 60;
|
||||
}
|
||||
VasEBoot_printf ("%02d:%02d:%02d", h, m, s);
|
||||
}
|
||||
else
|
||||
VasEBoot_printf ("invalid or vendor-specific");
|
||||
}
|
||||
|
||||
static int get_int_arg (const struct VasEBoot_arg_list *state)
|
||||
{
|
||||
return (state->set ? (int)VasEBoot_strtoul (state->arg, 0, 0) : -1);
|
||||
}
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_hdparm (VasEBoot_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct VasEBoot_arg_list *state = ctxt->state;
|
||||
struct VasEBoot_ata *ata;
|
||||
const char *diskname;
|
||||
|
||||
/* Check command line. */
|
||||
if (argc != 1)
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
|
||||
if (args[0][0] == '(')
|
||||
{
|
||||
VasEBoot_size_t len = VasEBoot_strlen (args[0]);
|
||||
if (args[0][len - 1] == ')')
|
||||
args[0][len - 1] = 0;
|
||||
diskname = &args[0][1];
|
||||
}
|
||||
else
|
||||
diskname = &args[0][0];
|
||||
|
||||
int i = 0;
|
||||
int apm = get_int_arg (&state[i++]);
|
||||
int power = state[i++].set;
|
||||
int sec_freeze = state[i++].set;
|
||||
int health = state[i++].set;
|
||||
int aam = get_int_arg (&state[i++]);
|
||||
int standby_tout = get_int_arg (&state[i++]);
|
||||
int standby_now = state[i++].set;
|
||||
int sleep_now = state[i++].set;
|
||||
int ident = state[i++].set;
|
||||
int dumpid = state[i++].set;
|
||||
int enable_smart = get_int_arg (&state[i++]);
|
||||
quiet = state[i++].set;
|
||||
|
||||
/* Open disk. */
|
||||
VasEBoot_disk_t disk = VasEBoot_disk_open (diskname);
|
||||
if (! disk)
|
||||
return VasEBoot_errno;
|
||||
|
||||
switch (disk->dev->id)
|
||||
{
|
||||
case VAS_EBOOT_DISK_DEVICE_ATA_ID:
|
||||
ata = disk->data;
|
||||
break;
|
||||
case VAS_EBOOT_DISK_DEVICE_SCSI_ID:
|
||||
if (((disk->id >> VAS_EBOOT_SCSI_ID_SUBSYSTEM_SHIFT) & 0xFF)
|
||||
== VAS_EBOOT_SCSI_SUBSYSTEM_PATA
|
||||
|| (((disk->id >> VAS_EBOOT_SCSI_ID_SUBSYSTEM_SHIFT) & 0xFF)
|
||||
== VAS_EBOOT_SCSI_SUBSYSTEM_AHCI))
|
||||
{
|
||||
ata = ((struct VasEBoot_scsi *) disk->data)->data;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
VasEBoot_disk_close (disk);
|
||||
return VasEBoot_error (VAS_EBOOT_ERR_IO, "not an ATA device");
|
||||
}
|
||||
|
||||
|
||||
/* Change settings. */
|
||||
if (aam >= 0)
|
||||
VasEBoot_hdparm_set_val_cmd ("Automatic Acoustic Management", (aam ? aam : -1),
|
||||
ata, VAS_EBOOT_ATA_CMD_SET_FEATURES,
|
||||
(aam ? 0x42 : 0xc2), aam);
|
||||
|
||||
if (apm >= 0)
|
||||
VasEBoot_hdparm_set_val_cmd ("Advanced Power Management",
|
||||
(apm != 255 ? apm : -1), ata,
|
||||
VAS_EBOOT_ATA_CMD_SET_FEATURES,
|
||||
(apm != 255 ? 0x05 : 0x85),
|
||||
(apm != 255 ? apm : 0));
|
||||
|
||||
if (standby_tout >= 0)
|
||||
{
|
||||
if (! quiet)
|
||||
{
|
||||
VasEBoot_printf ("Set standby timeout to %d (", standby_tout);
|
||||
VasEBoot_hdparm_print_standby_tout (standby_tout);
|
||||
VasEBoot_printf (")");
|
||||
}
|
||||
/* The IDLE cmd sets disk to idle mode and configures standby timer. */
|
||||
VasEBoot_hdparm_set_val_cmd ("", -1, ata, VAS_EBOOT_ATA_CMD_IDLE, 0, standby_tout);
|
||||
}
|
||||
|
||||
if (enable_smart >= 0)
|
||||
{
|
||||
if (! quiet)
|
||||
VasEBoot_printf ("%sable SMART operations", (enable_smart ? "En" : "Dis"));
|
||||
int err = VasEBoot_hdparm_do_smart_cmd (ata, (enable_smart ?
|
||||
VAS_EBOOT_ATA_FEAT_SMART_ENABLE : VAS_EBOOT_ATA_FEAT_SMART_DISABLE));
|
||||
if (! quiet)
|
||||
VasEBoot_printf ("%s\n", err ? ": not supported" : "");
|
||||
}
|
||||
|
||||
if (sec_freeze)
|
||||
VasEBoot_hdparm_simple_cmd ("Freeze security settings", ata,
|
||||
VAS_EBOOT_ATA_CMD_SECURITY_FREEZE_LOCK);
|
||||
|
||||
/* Print/dump IDENTIFY. */
|
||||
if (ident || dumpid)
|
||||
{
|
||||
VasEBoot_uint16_t buf[VAS_EBOOT_DISK_SECTOR_SIZE / 2];
|
||||
if (VasEBoot_hdparm_do_ata_cmd (ata, VAS_EBOOT_ATA_CMD_IDENTIFY_DEVICE,
|
||||
0, 0, buf, sizeof (buf)))
|
||||
VasEBoot_printf ("Cannot read ATA IDENTIFY data\n");
|
||||
else
|
||||
{
|
||||
if (ident)
|
||||
VasEBoot_hdparm_print_identify (buf);
|
||||
if (dumpid)
|
||||
hexdump (0, (char *) buf, sizeof (buf));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check power mode. */
|
||||
if (power)
|
||||
{
|
||||
VasEBoot_printf ("Disk power mode is: ");
|
||||
int mode = VasEBoot_hdparm_do_check_powermode_cmd (ata);
|
||||
if (mode < 0)
|
||||
VasEBoot_printf ("unknown\n");
|
||||
else
|
||||
VasEBoot_printf ("%s (0x%02x)\n",
|
||||
(mode == 0xff ? "active/idle" :
|
||||
mode == 0x80 ? "idle" :
|
||||
mode == 0x00 ? "standby" : "unknown"), mode);
|
||||
}
|
||||
|
||||
/* Check health. */
|
||||
int status = 0;
|
||||
if (health)
|
||||
{
|
||||
if (! quiet)
|
||||
VasEBoot_printf ("SMART status is: ");
|
||||
int err = VasEBoot_hdparm_do_smart_cmd (ata, VAS_EBOOT_ATA_FEAT_SMART_STATUS);
|
||||
if (! quiet)
|
||||
VasEBoot_printf ("%s\n", (err < 0 ? "unknown" :
|
||||
err == 0 ? "OK" : "*BAD*"));
|
||||
status = (err > 0);
|
||||
}
|
||||
|
||||
/* Change power mode. */
|
||||
if (standby_now)
|
||||
VasEBoot_hdparm_simple_cmd ("Set disk to standby mode", ata,
|
||||
VAS_EBOOT_ATA_CMD_STANDBY_IMMEDIATE);
|
||||
|
||||
if (sleep_now)
|
||||
VasEBoot_hdparm_simple_cmd ("Set disk to sleep mode", ata,
|
||||
VAS_EBOOT_ATA_CMD_SLEEP);
|
||||
|
||||
VasEBoot_disk_close (disk);
|
||||
|
||||
VasEBoot_errno = VAS_EBOOT_ERR_NONE;
|
||||
return status;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(hdparm)
|
||||
{
|
||||
cmd = VasEBoot_register_extcmd_lockdown ("hdparm", VasEBoot_cmd_hdparm, 0,
|
||||
N_("[OPTIONS] DISK"),
|
||||
N_("Get/set ATA disk parameters."), options);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(hdparm)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd);
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/* help.c - command to show a help text. */
|
||||
/*
|
||||
* VAS_EBOOT -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* VAS_EBOOT 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.
|
||||
*
|
||||
* VAS_EBOOT 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 VAS_EBOOT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <VasEBoot/dl.h>
|
||||
#include <VasEBoot/misc.h>
|
||||
#include <VasEBoot/term.h>
|
||||
#include <VasEBoot/extcmd.h>
|
||||
#include <VasEBoot/i18n.h>
|
||||
#include <VasEBoot/mm.h>
|
||||
#include <VasEBoot/normal.h>
|
||||
#include <VasEBoot/charset.h>
|
||||
|
||||
VAS_EBOOT_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static VasEBoot_err_t
|
||||
VasEBoot_cmd_help (VasEBoot_extcmd_context_t ctxt __attribute__ ((unused)), int argc,
|
||||
char **args)
|
||||
{
|
||||
int cnt = 0;
|
||||
char *currarg;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
VasEBoot_command_t cmd;
|
||||
FOR_COMMANDS(cmd)
|
||||
{
|
||||
if ((cmd->prio & VAS_EBOOT_COMMAND_FLAG_ACTIVE))
|
||||
{
|
||||
struct VasEBoot_term_output *term;
|
||||
const char *summary_translated = _(cmd->summary);
|
||||
char *command_help;
|
||||
VasEBoot_uint32_t *unicode_command_help;
|
||||
VasEBoot_uint32_t *unicode_last_position;
|
||||
|
||||
command_help = VasEBoot_xasprintf ("%s %s", cmd->name, summary_translated);
|
||||
if (!command_help)
|
||||
break;
|
||||
|
||||
VasEBoot_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
|
||||
&unicode_last_position);
|
||||
|
||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||
{
|
||||
unsigned stringwidth;
|
||||
VasEBoot_uint32_t *unicode_last_screen_position;
|
||||
|
||||
unicode_last_screen_position = unicode_command_help;
|
||||
|
||||
stringwidth = 0;
|
||||
|
||||
while (unicode_last_screen_position < unicode_last_position &&
|
||||
stringwidth < ((VasEBoot_term_width (term) / 2) - 2))
|
||||
{
|
||||
struct VasEBoot_unicode_glyph glyph;
|
||||
unicode_last_screen_position
|
||||
+= VasEBoot_unicode_aglomerate_comb (unicode_last_screen_position,
|
||||
unicode_last_position
|
||||
- unicode_last_screen_position,
|
||||
&glyph);
|
||||
|
||||
stringwidth
|
||||
+= VasEBoot_term_getcharwidth (term, &glyph);
|
||||
}
|
||||
|
||||
VasEBoot_print_ucs4 (unicode_command_help,
|
||||
unicode_last_screen_position, 0, 0, term);
|
||||
if (!(cnt % 2))
|
||||
VasEBoot_print_spaces (term, VasEBoot_term_width (term) / 2
|
||||
- stringwidth);
|
||||
}
|
||||
|
||||
if (cnt % 2)
|
||||
VasEBoot_printf ("\n");
|
||||
cnt++;
|
||||
|
||||
VasEBoot_free (command_help);
|
||||
VasEBoot_free (unicode_command_help);
|
||||
}
|
||||
}
|
||||
if (!(cnt % 2))
|
||||
VasEBoot_printf ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
VasEBoot_command_t cmd_iter, cmd, cmd_next;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
currarg = args[i];
|
||||
|
||||
FOR_COMMANDS_SAFE (cmd_iter, cmd_next)
|
||||
{
|
||||
if (!(cmd_iter->prio & VAS_EBOOT_COMMAND_FLAG_ACTIVE))
|
||||
continue;
|
||||
|
||||
if (VasEBoot_strncmp (cmd_iter->name, currarg,
|
||||
VasEBoot_strlen (currarg)) != 0)
|
||||
continue;
|
||||
if (cmd_iter->flags & VAS_EBOOT_COMMAND_FLAG_DYNCMD)
|
||||
cmd = VasEBoot_dyncmd_get_cmd (cmd_iter);
|
||||
else
|
||||
cmd = cmd_iter;
|
||||
if (!cmd)
|
||||
{
|
||||
VasEBoot_print_error ();
|
||||
continue;
|
||||
}
|
||||
if (cnt++ > 0)
|
||||
VasEBoot_printf ("\n\n");
|
||||
|
||||
if ((cmd->flags & VAS_EBOOT_COMMAND_FLAG_EXTCMD) &&
|
||||
! (cmd->flags & VAS_EBOOT_COMMAND_FLAG_DYNCMD))
|
||||
VasEBoot_arg_show_help ((VasEBoot_extcmd_t) cmd->data);
|
||||
else
|
||||
VasEBoot_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name,
|
||||
_(cmd->summary), _(cmd->description));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VasEBoot_printf ("\n\nTo enable less(1)-like paging, \"set pager=1\".\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VasEBoot_extcmd_t cmd;
|
||||
|
||||
VAS_EBOOT_MOD_INIT(help)
|
||||
{
|
||||
cmd = VasEBoot_register_extcmd ("help", VasEBoot_cmd_help, 0,
|
||||
N_("[PATTERN ...]"),
|
||||
N_("Show a help message."), 0);
|
||||
}
|
||||
|
||||
VAS_EBOOT_MOD_FINI(help)
|
||||
{
|
||||
VasEBoot_unregister_extcmd (cmd);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue