OK, this has no right to be in here... "as developed primarily through reverse-engineering of the original MS bios and its boot process."

A diff will be provided in the future.

svn path=/trunk/; revision=31201
This commit is contained in:
Daniel Reimer 2007-12-13 17:03:01 +00:00
parent 3f301b6835
commit 44083c8d46
259 changed files with 0 additions and 61451 deletions

View file

@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View file

@ -1,219 +0,0 @@
CC = gcc
# prepare check for gcc 3.3, $(GCC_3.3) will either be 0 or 1
GCC_3.3 := $(shell expr `$(CC) -dumpversion` \>= 3.3)
ETHERBOOT := yes
INCLUDE = -I$(TOPDIR)/grub -I$(TOPDIR)/include -I$(TOPDIR)/ -I./ -I$(TOPDIR)/fs/cdrom \
-I$(TOPDIR)/fs/fatx -I$(TOPDIR)/lib/eeprom -I$(TOPDIR)/lib/crypt \
-I$(TOPDIR)/drivers/video -I$(TOPDIR)/drivers/ide -I$(TOPDIR)/drivers/flash -I$(TOPDIR)/lib/misc \
-I$(TOPDIR)/boot_xbe/ -I$(TOPDIR)/fs/grub -I$(TOPDIR)/lib/font \
-I$(TOPDIR)/startuploader -I$(TOPDIR)/drivers/cpu \
-I$(TOPDIR)/lib/jpeg/
CFLAGS = -O2 -mcpu=pentium -Werror $(INCLUDE) -Wstrict-prototypes -fomit-frame-pointer -pipe
# add the option for gcc 3.3 only
ifeq ($(GCC_3.3), 1)
CFLAGS += -fno-zero-initialized-in-bss
endif
LD = ld
OBJCOPY = objcopy
export CC
TOPDIR := $(shell /bin/pwd)
SUBDIRS = boot_rom fs drivers lib boot
#### Etherboot specific stuff
ifeq ($(ETHERBOOT), yes)
ETH_SUBDIRS = etherboot
CFLAGS += -DETHERBOOT
ETH_INCLUDE = -I$(TOPDIR)/etherboot/include -I$(TOPDIR)/etherboot/arch/i386/include
ETH_CFLAGS = -O2 -mcpu=pentium -Werror $(ETH_INCLUDE) -Wstrict-prototypes -fomit-frame-pointer -pipe -Ui386
endif
LDFLAGS-ROM = -s -S -T $(TOPDIR)/scripts/ldscript-crom.ld
LDFLAGS-XBEBOOT = -s -S -T $(TOPDIR)/scripts/xbeboot.ld
LDFLAGS-ROMBOOT = -s -S -T $(TOPDIR)/boot_rom/bootrom.ld
LDFLAGS-VMLBOOT = -s -S -T $(TOPDIR)/boot_vml/vml_start.ld
ifeq ($(ETHERBOOT), yes)
LDFLAGS-ETHBOOT = -s -S -T $(TOPDIR)/boot_eth/eth_start.ld
endif
# add the option for gcc 3.3 only
ifeq ($(GCC_3.3), 1)
ETH_CFLAGS += -fno-zero-initialized-in-bss
endif
#### End Etherboot specific stuff
OBJECTS-XBE = $(TOPDIR)/boot_xbe/xbeboot.o
OBJECTS-VML = $(TOPDIR)/boot_vml/vml_Startup.o
ifeq ($(ETHERBOOT), yes)
OBJECTS-ETH = $(TOPDIR)/boot_eth/eth_Startup.o
endif
OBJECTS-ROMBOOT = $(TOPDIR)/obj/2bBootStartup.o
OBJECTS-ROMBOOT += $(TOPDIR)/obj/2bPicResponseAction.o
OBJECTS-ROMBOOT += $(TOPDIR)/obj/2bBootStartBios.o
OBJECTS-ROMBOOT += $(TOPDIR)/obj/sha1.o
OBJECTS-ROMBOOT += $(TOPDIR)/obj/2bBootLibrary.o
OBJECTS-ROMBOOT += $(TOPDIR)/obj/misc.o
OBJECTS-CROM = $(TOPDIR)/obj/BootStartup.o
OBJECTS-CROM += $(TOPDIR)/obj/BootResetAction.o
OBJECTS-CROM += $(TOPDIR)/obj/i2cio.o
OBJECTS-CROM += $(TOPDIR)/obj/pci.o
OBJECTS-CROM += $(TOPDIR)/obj/BootVgaInitialization.o
OBJECTS-CROM += $(TOPDIR)/obj/VideoInitialization.o
OBJECTS-CROM += $(TOPDIR)/obj/conexant.o
OBJECTS-CROM += $(TOPDIR)/obj/focus.o
OBJECTS-CROM += $(TOPDIR)/obj/xcalibur.o
OBJECTS-CROM += $(TOPDIR)/obj/BootIde.o
OBJECTS-CROM += $(TOPDIR)/obj/BootHddKey.o
OBJECTS-CROM += $(TOPDIR)/obj/rc4.o
OBJECTS-CROM += $(TOPDIR)/obj/sha1.o
OBJECTS-CROM += $(TOPDIR)/obj/BootVideoHelpers.o
OBJECTS-CROM += $(TOPDIR)/obj/vsprintf.o
OBJECTS-CROM += $(TOPDIR)/obj/IconMenu.o
OBJECTS-CROM += $(TOPDIR)/obj/TextMenu.o
OBJECTS-CROM += $(TOPDIR)/obj/TextMenuInit.o
OBJECTS-CROM += $(TOPDIR)/obj/MenuActions.o
OBJECTS-CROM += $(TOPDIR)/obj/BootFromDevice.o
OBJECTS-CROM += $(TOPDIR)/obj/LoadLinux.o
OBJECTS-CROM += $(TOPDIR)/obj/LoadReactOS.o
OBJECTS-CROM += $(TOPDIR)/obj/setup.o
OBJECTS-CROM += $(TOPDIR)/obj/iso9660.o
OBJECTS-CROM += $(TOPDIR)/obj/BootLibrary.o
OBJECTS-CROM += $(TOPDIR)/obj/cputools.o
OBJECTS-CROM += $(TOPDIR)/obj/microcode.o
OBJECTS-CROM += $(TOPDIR)/obj/ioapic.o
OBJECTS-CROM += $(TOPDIR)/obj/BootInterrupts.o
OBJECTS-CROM += $(TOPDIR)/obj/fsys_reiserfs.o
OBJECTS-CROM += $(TOPDIR)/obj/fsys_ext2fs.o
OBJECTS-CROM += $(TOPDIR)/obj/char_io.o
OBJECTS-CROM += $(TOPDIR)/obj/disk_io.o
OBJECTS-CROM += $(TOPDIR)/obj/decode-jpg.o
OBJECTS-CROM += $(TOPDIR)/obj/BootFlash.o
OBJECTS-CROM += $(TOPDIR)/obj/BootFlashUi.o
OBJECTS-CROM += $(TOPDIR)/obj/BootEEPROM.o
OBJECTS-CROM += $(TOPDIR)/obj/BootParser.o
OBJECTS-CROM += $(TOPDIR)/obj/BootFATX.o
#USB
OBJECTS-CROM += $(TOPDIR)/obj/config.o
OBJECTS-CROM += $(TOPDIR)/obj/hcd-pci.o
OBJECTS-CROM += $(TOPDIR)/obj/hcd.o
OBJECTS-CROM += $(TOPDIR)/obj/hub.o
OBJECTS-CROM += $(TOPDIR)/obj/message.o
OBJECTS-CROM += $(TOPDIR)/obj/ohci-hcd.o
OBJECTS-CROM += $(TOPDIR)/obj/buffer_simple.o
OBJECTS-CROM += $(TOPDIR)/obj/urb.o
OBJECTS-CROM += $(TOPDIR)/obj/usb-debug.o
OBJECTS-CROM += $(TOPDIR)/obj/usb.o
OBJECTS-CROM += $(TOPDIR)/obj/BootUSB.o
OBJECTS-CROM += $(TOPDIR)/obj/usbwrapper.o
OBJECTS-CROM += $(TOPDIR)/obj/linuxwrapper.o
OBJECTS-CROM += $(TOPDIR)/obj/xpad.o
OBJECTS-CROM += $(TOPDIR)/obj/xremote.o
OBJECTS-CROM += $(TOPDIR)/obj/usbkey.o
OBJECTS-CROM += $(TOPDIR)/obj/risefall.o
#ETHERBOOT
ifeq ($(ETHERBOOT), yes)
OBJECTS-CROM += $(TOPDIR)/obj/nfs.o
OBJECTS-CROM += $(TOPDIR)/obj/nic.o
OBJECTS-CROM += $(TOPDIR)/obj/osloader.o
OBJECTS-CROM += $(TOPDIR)/obj/xbox.o
OBJECTS-CROM += $(TOPDIR)/obj/forcedeth.o
OBJECTS-CROM += $(TOPDIR)/obj/xbox_misc.o
OBJECTS-CROM += $(TOPDIR)/obj/xbox_pci.o
OBJECTS-CROM += $(TOPDIR)/obj/etherboot_config.o
OBJECTS-CROM += $(TOPDIR)/obj/xbox_main.o
OBJECTS-CROM += $(TOPDIR)/obj/elf.o
endif
RESOURCES = $(TOPDIR)/obj/backdrop.elf
export INCLUDE
export TOPDIR
ifeq ($(ETHERBOOT), yes)
BOOT_ETH_DIR = boot_eth/ethboot
BOOT_ETH_SUBDIRS = ethsubdirs
endif
all: clean resources $(BOOT_ETH_SUBDIRS) cromsubdirs default.xbe vmlboot $(BOOT_ETH_DIR) image.bin imagecompress
ifeq ($(ETHERBOOT), yes)
ethsubdirs: $(patsubst %, _dir_%, $(ETH_SUBDIRS))
$(patsubst %, _dir_%, $(ETH_SUBDIRS)) : dummy
$(MAKE) CFLAGS="$(ETH_CFLAGS)" -C $(patsubst _dir_%, %, $@)
endif
cromsubdirs: $(patsubst %, _dir_%, $(SUBDIRS))
$(patsubst %, _dir_%, $(SUBDIRS)) : dummy
$(MAKE) CFLAGS="$(CFLAGS)" -C $(patsubst _dir_%, %, $@)
dummy:
resources:
# Background
${LD} -r --oformat elf32-i386 -o $(TOPDIR)/obj/backdrop.elf -T $(TOPDIR)/scripts/backdrop.ld -b binary $(TOPDIR)/pics/backdrop.jpg
install:
lmilk -f -p $(TOPDIR)/image/image.bin
lmilk -f -a c0000 -p $(TOPDIR)/image/image.bin -q
clean:
find . \( -name '*.[oas]' -o -name core -o -name '.*.flags' \) -type f -print \
| grep -v lxdialog/ | xargs rm -f
rm -f $(TOPDIR)/obj/*.gz
rm -f $(TOPDIR)/obj/*.bin
rm -f $(TOPDIR)/obj/*.elf
rm -f $(TOPDIR)/image/*.bin
rm -f $(TOPDIR)/image/*.xbe
rm -f $(TOPDIR)/xbe/*.xbe $(TOPDIR)/xbe/*.bin
rm -f $(TOPDIR)/xbe/*.elf
rm -f $(TOPDIR)/image/*.bin
rm -f $(TOPDIR)/bin/imagebld*
rm -f $(TOPDIR)/boot_vml/disk/vmlboot
rm -f boot_eth/ethboot
mkdir -p $(TOPDIR)/xbe
mkdir -p $(TOPDIR)/image
mkdir -p $(TOPDIR)/obj
mkdir -p $(TOPDIR)/bin
obj/image-crom.bin:
${LD} -o obj/image-crom.elf ${OBJECTS-CROM} ${RESOURCES} ${LDFLAGS-ROM}
${OBJCOPY} --output-target=binary --strip-all obj/image-crom.elf $@
vmlboot: ${OBJECTS-VML}
${LD} -o $(TOPDIR)/obj/vmlboot.elf ${OBJECTS-VML} ${LDFLAGS-VMLBOOT}
${OBJCOPY} --output-target=binary --strip-all $(TOPDIR)/obj/vmlboot.elf $(TOPDIR)/boot_vml/disk/$@
ifeq ($(ETHERBOOT), yes)
boot_eth/ethboot: ${OBJECTS-ETH} obj/image-crom.bin
${LD} -o obj/ethboot.elf ${OBJECTS-ETH} -b binary obj/image-crom.bin ${LDFLAGS-ETHBOOT}
${OBJCOPY} --output-target=binary --strip-all obj/ethboot.elf obj/ethboot.bin
perl -I boot_eth boot_eth/mknbi.pl --output=$@ obj/ethboot.bin
endif
default.xbe: ${OBJECTS-XBE}
${LD} -o $(TOPDIR)/obj/default.elf ${OBJECTS-XBE} ${LDFLAGS-XBEBOOT}
${OBJCOPY} --output-target=binary --strip-all $(TOPDIR)/obj/default.elf $(TOPDIR)/xbe/$@
image.bin:
${LD} -o $(TOPDIR)/obj/2lbimage.elf ${OBJECTS-ROMBOOT} ${LDFLAGS-ROMBOOT}
${OBJCOPY} --output-target=binary --strip-all $(TOPDIR)/obj/2lbimage.elf $(TOPDIR)/obj/2blimage.bin
# This is a local executable, so don't use a cross compiler...
bin/imagebld: lib/imagebld/imagebld.c lib/crypt/sha1.c
gcc -Ilib/crypt -o bin/sha1.o -c lib/crypt/sha1.c
gcc -Ilib/crypt -o bin/imagebld.o -c lib/imagebld/imagebld.c
gcc -o bin/imagebld bin/imagebld.o bin/sha1.o
imagecompress: obj/image-crom.bin bin/imagebld
cp obj/image-crom.bin obj/image-crom.bin.tmp
gzip -9 obj/image-crom.bin.tmp
bin/imagebld -rom obj/2blimage.bin obj/image-crom.bin.tmp.gz image/image.bin image/image_1024.bin
bin/imagebld -xbe xbe/default.xbe obj/image-crom.bin
bin/imagebld -vml boot_vml/disk/vmlboot obj/image-crom.bin

View file

@ -1,66 +0,0 @@
#
# This file contains rules which are shared between multiple Makefiles.
#
EXTRA_CFLAGS += -I$(TOPDIR)/include -I$(TOPDIR)/fs/cdrom -I$(TOPDIR)/drivers/video -I$(TOPDIR)/lib/eeprom -I$(TOPDIR)/lib/misc
#
# False targets.
#
.PHONY: dummy
CFLAGSBR = -Wall -Werror
#
# Special variables which should not be exported
#
unexport subdirs
comma := ,
#
# Get things started.
#
first_rule: sub_dirs
$(MAKE) all_targets
SUB_DIRS := $(subdir)
#
# Common rules
#
BootPerformPicChallengeResponseAction.o: BootPerformPicChallengeResponseAction.c
$(CC) $(CFLAGSBR) $(INCLUDE) -o $(TOPDIR)/obj/$@ -c $<
%.o : %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -o $(TOPDIR)/obj/$@ -c $<
%.o : %.S
$(CC) -DASSEMBLER $(CFLAGS) $(EXTRA_CFLAGS) -o $(TOPDIR)/obj/$@ -c $<
all_targets: $(O_TARGET)
$(O_TARGET): $(obj)
#
# A rule to make subdirectories
#
subdir-list = $(sort $(patsubst %,_subdir_%,$(SUB_DIRS)))
sub_dirs: dummy $(subdir-list)
ifdef SUB_DIRS
$(subdir-list) : dummy
$(MAKE) -C $(patsubst _subdir_%,%,$@)
endif
#
# A rule to do nothing
#
dummy:
#
# This is useful for testing
#
script:
$(SCRIPT)

View file

@ -1,215 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "boot.h"
#include "video.h"
#include "BootFATX.h"
#include "BootFromDevice.h"
#include "IconMenu.h"
#include "LoadLinux.h"
#include "LoadReactOS.h"
static void SelectOS(void (*LinuxBoot)(void *), void (*ReactOSBoot)(void *), void *Context)
{
PICONMENU Menu;
PICON iconPtr=0l;
Menu = CreateIconMenu();
if (NULL == Menu) {
return;
}
iconPtr = (PICON)malloc(sizeof(ICON));
if (NULL == iconPtr) {
DestroyIconMenu(Menu);
return;
}
iconPtr->iconSlot = ICON_SOURCE_SLOT5;
iconPtr->szCaption = "Linux";
iconPtr->functionPtr = LinuxBoot;
iconPtr->functionDataPtr = Context;
AddIcon(Menu, iconPtr, false);
iconPtr = (PICON)malloc(sizeof(ICON));
if (NULL == iconPtr) {
DestroyIconMenu(Menu);
return;
}
iconPtr->iconSlot = ICON_SOURCE_SLOT6;
iconPtr->szCaption = "ReactOS";
iconPtr->functionPtr = ReactOSBoot;
iconPtr->functionDataPtr = Context;
AddIcon(Menu, iconPtr, false);
DisplayIconMenu(Menu, true);
DestroyIconMenu(Menu);
}
static void CallBootLinuxFromCD(void *Context)
{
BootLinuxFromCD(*((int *) Context));
}
static void CallBootReactOSFromCD(void *Context)
{
BootReactOSFromCD(*((int *) Context));
}
void BootFromCD(void *data) {
DWORD dwY=VIDEO_CURSOR_POSY;
DWORD dwX=VIDEO_CURSOR_POSX;
int n;
bool quit;
bool linuxPresent, reactosPresent;
int drive = *((int *) data);
//See if we already have a CDROM in the drive
//Try for 4 seconds.
for (n=0;n<16;++n) {
linuxPresent = LinuxPresentOnCD(drive);
reactosPresent = ReactOSPresentOnCD(drive);
if (linuxPresent || reactosPresent) {
break;
}
wait_ms(250);
}
if (! linuxPresent && ! reactosPresent) {
//Needs to be changed for non-xbox drives, which don't have an eject line
//Need to send ATA eject command.
I2CTransmitWord(0x10, 0x0c00); // eject DVD tray
wait_ms(2000); // Wait for DVD to become responsive to inject command
VIDEO_ATTR=0xffeeeeff;
VIDEO_CURSOR_POSX=dwX;
VIDEO_CURSOR_POSY=dwY;
printk("Please insert CD and press Button A\n");
while(1) {
if (risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_A) == 1) {
quit = false;
break;
}
if (risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_B) == 1) {
quit = true;
break;
}
USBGetEvents();
wait_ms(10);
}
BootVideoClearScreen(&jpegBackdrop, dwY, VIDEO_CURSOR_POSY + 1);
I2CTransmitWord(0x10, 0x0c01); // close DVD tray
wait_ms(500);
VIDEO_ATTR = 0xffffffff;
VIDEO_CURSOR_POSY = dwY;
if (quit) {
return;
}
/* Wait until the media is readable */
while (1) {
linuxPresent = LinuxPresentOnCD(drive);
reactosPresent = ReactOSPresentOnCD(drive);
if (linuxPresent || reactosPresent) {
break;
}
if (risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_B) == 1) {
break;
}
USBGetEvents();
wait_ms(200);
}
}
if (linuxPresent && reactosPresent) {
SelectOS(CallBootLinuxFromCD, CallBootReactOSFromCD, data);
} else if (linuxPresent) {
BootLinuxFromCD(drive);
} else if (reactosPresent) {
BootReactOSFromCD(drive);
}
}
static void CallBootLinuxFromFATX(void *Context)
{
BootLinuxFromFATX();
}
static void CallBootReactOSFromFATX(void *Context)
{
BootReactOSFromFATX();
}
void BootFromFATX(void *Context) {
bool linuxPresent;
bool reactosPresent;
linuxPresent = LinuxPresentOnFATX(NULL);
reactosPresent = ReactOSPresentOnFATX(NULL);
if (linuxPresent && reactosPresent) {
SelectOS(CallBootLinuxFromFATX, CallBootReactOSFromFATX, NULL);
} else if (linuxPresent) {
BootLinuxFromFATX();
} else if (reactosPresent) {
BootReactOSFromFATX();
}
}
static void CallBootLinuxFromNative(void *Context)
{
BootLinuxFromNative(*((int *) Context));
}
static void CallBootReactOSFromNative(void *Context)
{
BootReactOSFromNative(*((int *) Context));
}
void BootFromNative(void *Context) {
int partitionId = *((int *) Context);
bool linuxPresent;
bool reactosPresent;
linuxPresent = LinuxPresentOnNative(partitionId);
reactosPresent = ReactOSPresentOnNative(partitionId);
if (linuxPresent && reactosPresent) {
SelectOS(CallBootLinuxFromNative, CallBootReactOSFromNative, Context);
} else if (linuxPresent) {
BootLinuxFromNative(partitionId);
} else if (reactosPresent) {
BootReactOSFromNative(partitionId);
}
}
#ifdef ETHERBOOT
static void CallBootLinuxFromEtherboot(void *Context)
{
BootLinuxFromEtherboot();
}
static void CallBootReactOSFromEtherboot(void *Context)
{
BootReactOSFromEtherboot();
}
void BootFromEtherboot(void *Context) {
bool linuxPresent;
bool reactosPresent;
linuxPresent = LinuxPresentOnEtherboot();
reactosPresent = ReactOSPresentOnEtherboot();
if (linuxPresent && reactosPresent) {
SelectOS(CallBootLinuxFromEtherboot, CallBootReactOSFromEtherboot, NULL);
} else if (linuxPresent) {
BootLinuxFromEtherboot();
} else if (reactosPresent) {
BootReactOSFromEtherboot();
}
}
#endif

View file

@ -1,19 +0,0 @@
#ifndef _BOOTFROMDEVICE_H_
#define _BOOTFROMDEVICE_H_
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
void BootFromCD(void *);
void BootFromFATX(void *);
void BootFromNative(void *);
#ifdef ETHERBOOT
void BootFromEtherboot(void *);
#endif
#endif

View file

@ -1,214 +0,0 @@
/*
* Sequences the necessary post-reset actions from as soon as we are able to run C
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
*/
#include "boot.h"
#include "BootEEPROM.h"
#include "BootFlash.h"
#include "BootFATX.h"
#include "xbox.h"
#include "cpu.h"
#include "config.h"
#include "video.h"
#include "memory_layout.h"
JPEG jpegBackdrop;
int nTempCursorMbrX, nTempCursorMbrY;
extern volatile int nInteruptable;
volatile CURRENT_VIDEO_MODE_DETAILS vmode;
extern KNOWN_FLASH_TYPE aknownflashtypesDefault[];
//////////////////////////////////////////////////////////////////////
//
// BootResetAction()
extern void BootResetAction ( void ) {
bool fMbrPresent=false;
bool fSeenActive=false;
int nFATXPresent=false;
int nTempCursorX, nTempCursorY;
int n, nx;
memcpy(&cromwell_config,(void*)(0x03A00000+0x20),4);
memcpy(&cromwell_retryload,(void*)(0x03A00000+0x24),4);
memcpy(&cromwell_loadbank,(void*)(0x03A00000+0x28),4);
memcpy(&cromwell_Biostype,(void*)(0x03A00000+0x2C),4);
VIDEO_CURSOR_POSX=40;
VIDEO_CURSOR_POSY=140;
VIDEO_AV_MODE = 0xff;
nInteruptable = 0;
// prep our BIOS console print state
VIDEO_ATTR=0xffffffff;
// init malloc() and free() structures
MemoryManagementInitialization((void *)MEMORYMANAGERSTART, MEMORYMANAGERSIZE);
BootInterruptsWriteIdt();
// initialize the PCI devices
//bprintf("BOOT: starting PCI init\n\r");
BootPciPeripheralInitialization();
// Reset the AGP bus and start with good condition
BootAGPBUSInitialization();
// We disable The CPU Cache
cache_disable();
// We Update the Microcode of the CPU
display_cpuid_update_microcode();
// We Enable The CPU Cache
cache_enable();
//setup_ioapic();
// We look how much memory we have ..
BootDetectMemorySize();
BootEepromReadEntireEEPROM();
bprintf("BOOT: Read EEPROM\n\r");
// Load and Init the Background image
// clear the Video Ram
memset((void *)FB_START,0x00,0x400000);
BootVgaInitializationKernelNG((CURRENT_VIDEO_MODE_DETAILS *)&vmode);
{ // decode and malloc backdrop bitmap
extern int _start_backdrop;
BootVideoJpegUnpackAsRgb(
(BYTE *)&_start_backdrop,
&jpegBackdrop
);
}
// display solid red frontpanel LED while we start up
I2cSetFrontpanelLed(I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3 );
// paint the backdrop
#ifndef DEBUG_MODE
BootVideoClearScreen(&jpegBackdrop, 0, 0xffff);
#endif
I2CTransmitWord(0x10, 0x1a01); // unknown, done immediately after reading out eeprom data
I2CTransmitWord(0x10, 0x1b04); // unknown
/* Here, the interrupts are Switched on now */
BootPciInterruptEnable();
/* We allow interrupts */
nInteruptable = 1;
I2CTransmitWord(0x10, 0x1901); // no reset on eject
VIDEO_CURSOR_POSY=vmode.ymargin;
VIDEO_CURSOR_POSX=(vmode.xmargin/*+64*/)*4;
if (cromwell_config==XROMWELL) printk("\2Xbox Linux Xromwell " VERSION "\2\n" );
if (cromwell_config==CROMWELL) printk("\2Xbox Linux Cromwell BIOS " VERSION "\2\n" );
VIDEO_CURSOR_POSY=vmode.ymargin+32;
VIDEO_CURSOR_POSX=(vmode.xmargin/*+64*/)*4;
printk( __DATE__ " - http://xbox-linux.org\n");
VIDEO_CURSOR_POSX=(vmode.xmargin/*+64*/)*4;
printk("(C)2002-2004 Xbox Linux Team RAM : %d MB ",xbox_ram);
printk("\n");
// capture title area
VIDEO_ATTR=0xffc8c8c8;
printk("Encoder: ");
VIDEO_ATTR=0xffc8c800;
printk("%s ", VideoEncoderName());
VIDEO_ATTR=0xffc8c8c8;
printk("Cable: ");
VIDEO_ATTR=0xffc8c800;
printk("%s ", AvCableName());
if (I2CGetTemperature(&n, &nx)) {
VIDEO_ATTR=0xffc8c8c8;
printk("CPU Temp: ");
VIDEO_ATTR=0xffc8c800;
printk("%doC ", n);
VIDEO_ATTR=0xffc8c8c8;
printk("M/b Temp: ");
VIDEO_ATTR=0xffc8c800;
printk("%doC ", nx);
}
printk("\n");
nTempCursorX=VIDEO_CURSOR_POSX;
nTempCursorY=VIDEO_CURSOR_POSY;
I2cSetFrontpanelLed(I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3 );
VIDEO_ATTR=0xffffffff;
// gggb while waiting for Ethernet & Hdd
I2cSetFrontpanelLed(I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_GREEN2);
// set Ethernet MAC address from EEPROM
{
volatile BYTE * pb=(BYTE *)0xfef000a8; // Ethernet MMIO base + MAC register offset (<--thanks to Anders Gustafsson)
int n;
for(n=5;n>=0;n--) { *pb++= eeprom.MACAddress[n]; } // send it in backwards, its reversed by the driver
}
BootEepromPrintInfo();
#ifdef FLASH
{
OBJECT_FLASH of;
memset(&of,0x00,sizeof(of));
of.m_pbMemoryMappedStartAddress=(BYTE *)LPCFlashadress;
BootFlashGetDescriptor(&of, (KNOWN_FLASH_TYPE *)&aknownflashtypesDefault[0]);
VIDEO_ATTR=0xffc8c8c8;
printk("Flash type: ");
VIDEO_ATTR=0xffc8c800;
printk("%s\n", of.m_szFlashDescription);
}
#endif
printk("BOOT: start USB init\n");
BootStartUSB();
// init the IDE devices
VIDEO_ATTR=0xffc8c8c8;
printk("Initializing IDE Controller\n");
BootIdeWaitNotBusy(0x1f0);
wait_ms(200);
printk("Ready\n");
// reuse BIOS status area
#ifndef DEBUG_MODE
BootVideoClearScreen(&jpegBackdrop, nTempCursorY, VIDEO_CURSOR_POSY+1); // blank out volatile data area
#endif
VIDEO_CURSOR_POSX=nTempCursorX;
VIDEO_CURSOR_POSY=nTempCursorY;
bprintf("Entering BootIdeInit()\n");
BootIdeInit();
printk("\n");
nTempCursorMbrX=VIDEO_CURSOR_POSX;
nTempCursorMbrY=VIDEO_CURSOR_POSY;
// if we made it this far, lets have a solid green LED to celebrate
I2cSetFrontpanelLed(
I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_GREEN2 | I2C_LED_GREEN3
);
// printk("i2C=%d SMC=%d, IDE=%d, tick=%d una=%d unb=%d\n", nCountI2cinterrupts, nCountInterruptsSmc, nCountInterruptsIde, BIOS_TICK_COUNT, nCountUnusedInterrupts, nCountUnusedInterruptsPic2);
MainMenu();
//Should never come back here.
while(1);
}

View file

@ -1,817 +0,0 @@
/*
*
* BIOS ROM Startup Assembler
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "consts.h"
#include "memory_layout.h"
.code32
.section .text, "ax"
.org 0x00
jmp start_linux
.global Cromwellconfig
Cromwellconfig:
.org 0x0c
// Space for the SHA1 checksum
.org 0x20
// The Value positions are fixed, do never change them, used everywhere
.long 0x0 // 0x20 if XBE, then this bit is 0, if Cromwell mode, the bit is set to 1 by the Startuploader
.long 0x0 // 0x24 ImageRetryLoads
.long 0x0 // 0x28 Bank, from where Loaded
.long 0x0 // 0x2C 0 .. Bios = 256 k, 1 .. Bios = 1MB
.long 0x0 // 0x30 free
.long _end_compleate_rom // 0x34 free
.long 0x0 // 0x38 free
.long 0x0 // free
.align 16
tableGdt:
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0x00 dummy
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00 // 0x08 code32
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00 // 0x10 code32
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00 // 0x18 data32
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0x8f, 0x00 // 0x20 code16 (8f indicates 4K granularity, ie, huge limit)
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x8f, 0x00 // 0x28 data16
tableGdtDescriptor:
// This is the GDT header having 8 bytes
.word tableGdtDescriptor-tableGdt // 30 byte GDT
.long GDT_LOC // GDT located at 0xA0000
.word 0 // Padding
tableGdtEnd:
.align 16
tableIdtDescriptor:
.word 2048
.long IDT_LOC // IDT located at 0xB0000
.word 0 // fill Word, so we get alliged again
// We are again Dword Alligated now
.align 16
.globl start_linux
start_linux:
// i am sure, the irq's are turned off, but who knows this for sure
// never trust anybody
cli
// kill the cache = Disable bit 30 + 29 = CD + NW
// CD = Cache Disable (disable = 1)
// NW Not write through (disable = 1)
// mov %cr0, %eax
//orl $0x60000000, %eax
mov $0x60010033, %eax
mov %eax, %cr0
wbinvd
// Flush the TLB
xor %eax, %eax
mov %eax, %cr3
// We kill the Local Descriptor Table
xor %eax, %eax
lldt %ax
// DR6/DR7: Clear the debug registers
xor %eax, %eax
mov %eax, %dr6
mov %eax, %dr7
mov %eax, %dr0
mov %eax, %dr1
mov %eax, %dr2
mov %eax, %dr3
// IMPORTANT! Linux expects the GDT located at a specific position,
// 0xA0000, so we have to move it there.
// Copy the GDT to its final location
movl $GDT_LOC, %edi
movl $tableGdt, %esi
movl $(tableGdtEnd-tableGdt)/4, %ecx
rep movsl
// Load the new GDT
lgdt GDT_LOC+(tableGdtDescriptor-tableGdt)
// Kill the LDT, if any
xor %eax, %eax
lldt %ax
// Reload CS as 0010 from the new GDT using a far jump
.byte 0xEA // jmp far 0010:reload_cs
.long reload_cs
.word 0x0010
.align 16
reload_cs:
// CS is now a valid entry in the GDT. Set SS, DS, and ES to valid
// descriptors, but clear FS and GS as they are not necessary.
// Set SS, DS, and ES to a data32 segment with maximum limit.
movw $0x0018, %ax
mov %eax, %ss
mov %eax, %ds
mov %eax, %es
// Clear FS and GS
xor %eax, %eax
mov %eax, %fs
mov %eax, %gs
// Set the stack pointer to give us a valid stack
movl $STACK_TOP, %esp
// We clear the IDT in RAM (IDT located @ 0xb0000 )
xor %eax, %eax
movl $0x5000/4, %ecx
movl $IDT_LOC, %edi
rep stosl
wbinvd
// We load the Interrupt Descriptor Table
lidt tableIdtDescriptor
// FPU SETUP
xor %eax, %eax
xor %edx, %edx
xor %ecx, %ecx
clts
fninit
xor %eax, %eax
xor %edx, %edx
xor %ecx, %ecx
// We flush the TLB
mov %cr3, %eax
mov %eax, %cr3
// Clear Mmeory Type register
movl $0x2ff, %ecx
xor %eax, %eax
xor %edx, %edx
wrmsr
// MTRR for RAM
// from address 0, Writeback Caching, 128MB range
movl $0x200, %ecx
movl $0x00000000, %edx
movl $0x00000006, %eax // == WB_CACHE == 6
//movl $0x00000004, %eax // Temporary, as USB development
wrmsr
// MASK0 set to 0xf8000[000] == 128M
movl $0x201, %ecx
movl $0x0000000f, %edx
movl $0xf8000800, %eax
wrmsr
// MTRR for shadow RAM
// from address 0xf0000000, Write-combining Caching, 128MB range
movl $0x202, %ecx
movl $0x00000000, %edx
movl $0xf0000001, %eax // Write-Combining == 1
wrmsr
// MASK0 set to 0xf8000[000] == 128M
movl $0x203, %ecx
movl $0x0000000f, %edx
movl $0xf8000800, %eax
wrmsr
// MTRR for FLASH
movl $0x204, %ecx
movl $0x00000000, %edx
movl $0xFff00000, %eax // We set to Uncacheable
wrmsr
movl $0x205, %ecx
movl $0x0000000f, %edx
movl $0xfff00800, %eax
wrmsr
xor %eax, %eax
xor %edx, %edx
movl $0x206, %ecx // IA32_MTRR_PHYS Base 3
wrmsr
movl $0x207, %ecx // IA32_MTRR_PHYS_MASK 3
wrmsr
movl $0x208, %ecx // IA32_MTRR_PHYS Base 4
wrmsr
movl $0x209, %ecx // IA32_MTRR_PHYS_MASK 4
wrmsr
movl $0x20a, %ecx // IA32_MTRR_PHYS Base 5
wrmsr
movl $0x20b, %ecx // IA32_MTRR_PHYS_MASK 5
wrmsr
movl $0x20c, %ecx // IA32_MTRR_PHYS Base 6
wrmsr
movl $0x20d, %ecx // IA32_MTRR_PHYS_MASK 6
wrmsr
movl $0x20e, %ecx // IA32_MTRR_PHYS Base 7
wrmsr
movl $0x20f, %ecx // IA32_MTRR_PHYS_MASK 7
wrmsr
// Ok, we tell now the processor, we finished Memory Type definitions
// We set the Default Memory Type in the Box now to Type == 0 .. Means UC .. Uncacheable
movl $0x2ff, %ecx
xor %edx, %edx
movl $0x800, %eax //Enable MTRRs
wrmsr
// movl $0x600, %eax
// mov %eax, %cr4
mov %eax, %eax // Flush the TLB and resets it
mov %eax, %cr3
wbinvd
/* turn on normal cache */
// bit 30 + 29 = CD + NW
// CD = Cache Disable (disable = 1)
// NW Not write through (disable = 1)
// movl %cr0, %eax
// mov %eax, %ebx
// andl $0x9fFFffFF,%eax
// movl %eax, %cr0
// wbinvd
jmp BootResetAction
#if 0
// something for Video ?
mov $0x80000854, %eax
movw $0xcf8, %dx
outl %eax, %dx
movw $0xcfc, %dx
inl %dx, %eax
orl $0x88000000, %eax
outl %eax, %dx
wbinvd
// Important
mov $0x80000064, %eax
movw $0xcf8, %dx
outl %eax, %dx
movw $0xcfc, %dx
inl %dx, %eax
orl $0x88000000, %eax
outl %eax, %dx
wbinvd
// Important
mov $0x8000006c, %eax
movw $0xcf8, %dx
outl %eax, %dx
movw $0xcfc, %dx
inl %dx, %eax
push %eax
andl $0xfffffffe, %eax
outl %eax, %dx
pop %eax
outl %eax, %dx
wbinvd
/*
// CPU Whoami ? sesless ?
mov $0x80000080, %eax
movw $0xcf8, %dx
outl %eax, %dx
movw $0xcfc, %dx
movl $0x100, %eax
outl %eax, %dx
wbinvd
*/
mov $0x8000088C, %eax
movw $0xcf8, %dx
outl %eax, %dx
movw $0xcfc, %dx
movl $0x40000000, %eax
outl %eax, %dx
wbinvd
jmp BootResetAction
#endif
///////////////////////////////////////////
//
// Interrupt Service Routines
//
.global IntHandlerTimer0
IntHandlerTimer0:
cli
pusha
pushf
call IntHandlerCTimer0
mov $0x20, %al
outb %al, $0x20
popf
// sti
popa
iret
.global IntHandler1
IntHandler1:
pusha
pushf
cli
call IntHandler1C
mov $0x21, %al
outb %al, $0x20
popf
// sti
popa
iret
.global IntHandler2
IntHandler2:
cli
pusha
pushf
call IntHandler2C
mov $0x22, %al
outb %al, $0x20
popf
popa
// sti
iret
.global IntHandler3
IntHandler3:
cli
pusha
pushf
call IntHandler3VsyncC
mov $0x23, %al
outb %al, $0x20
popf
popa
// sti
iret
.global IntHandler4
IntHandler4:
cli
pusha
pushf
call IntHandler4C
mov $0x24, %al
outb %al, $0x20
popf
popa
// sti
iret
.global IntHandler5
IntHandler5:
cli
pusha
pushf
call IntHandler5C
mov $0x25, %al
outb %al, $0x20
popf
popa
// sti
iret
.global IntHandler6
IntHandler6:
cli
pusha
pushf
call IntHandler6C
mov $0x26, %al
outb %al, $0x20
popf
popa
sti
iret
.global IntHandler7
IntHandler7:
cli
pusha
pushf
call IntHandler7C
mov $0x27, %al
outb %al, $0x20
popf
popa
sti
iret
.global IntHandler8
IntHandler8:
cli
pusha
pushf
call IntHandler8C
// EOI on master and slave needed
mov $0x60, %al
out %al, $0xa0
mov $0x62, %al
out %al, $0x20
popf
popa
iret
.global IntHandler9
IntHandler9:
pusha
pushf
cli
call IntHandler9C
// EOI on master and slave needed
mov $0x61, %al
out %al, $0xa0
mov $0x62, %al
out %al, $0x20
popf
popa
iret
// Int 10 interrupts
.global IntHandler10
IntHandler10:
pusha
pushf
cli
call IntHandler10C
// EOI on master and slave needed
mov $0x62, %al
out %al, $0xa0
mov $0x62, %al
out %al, $0x20
popf
popa
iret
// Int 11 interrupts
.global IntHandlerI2C
IntHandlerI2C:
pusha
pushf
cli
call IntHandlerCI2C
// EOI on master and slave needed
mov $0x63, %al
out %al, $0xa0
mov $0x62, %al
out %al, $0x20
popf
popa
iret
// Int 12 interrupts
.global IntHandlerSmc
IntHandlerSmc:
cli
pusha
pushf
call IntHandlerCSmc
// acknowledge EXTSMI# action (from PIC p6)
mov $0x8020, %dx
inw %dx, %ax
or $0x0200, %ax
outw %ax, %dx
// EOI on master and slave needed
mov $0x64, %al // is int12
out %al, $0xa0
mov $0x62, %al // do cascaded master
out %al, $0x20
popf
popa
iret
// Int 13 interrupts
.global IntHandler13
IntHandler13:
cli
pusha
pushf
call IntHandler13C
// EOI on master and slave needed
mov $0x65, %al
out %al, $0xa0
mov $0x62, %al
out %al, $0x20
popf
popa
iret
// Int 14 interrupts
.global IntHandlerIde
IntHandlerIde:
cli
pusha
pushf
call IntHandlerCIde
// EOI on master and slave needed
mov $0x66, %al // was $0x20
out %al, $0xa0
mov $0x62, %al
out %al, $0x20
popf
popa
iret
// Int 15 interrupts
.global IntHandler15
IntHandler15:
cli
pusha
pushf
call IntHandler15C
// EOI on master and slave needed
mov $0x67, %al
out %al, $0xa0
mov $0x62, %al
out %al, $0x20
popf
popa
iret
// unused interrupts on master PIC
.global IntHandlerUnused
IntHandlerUnused:
cli
pusha
pushf
call IntHandlerUnusedC
mov $0x20, %al
out %al, $0x20
popf
popa
iret
// unused interrupts on slave PIC
.global IntHandlerUnusedPic2
IntHandlerUnusedPic2:
cli
pusha
pushf
call IntHandlerUnusedC2
mov $0xffff, %ax
mov $0x8028, %dx
outw %ax, %dx
mov $0x80cc, %dx
mov $0x40, %al
outb %al, %dx
mov $0x20, %al
out %al, $0xa0
mov $0x62, %al
out %al, $0x20
popf
popa
iret
.global SpareIntNop
SpareIntNop:
iret
// CPU Exception Interrupts
.global IntHandlerException0
IntHandlerException0:
pusha
pushf
cli
call IntHandlerException0C
popf
popa
iret
.global IntHandlerException1
IntHandlerException1:
pusha
pushf
cli
call IntHandlerException1C
popf
popa
iret
.global IntHandlerException2
IntHandlerException2:
pusha
pushf
cli
call IntHandlerException2C
popf
popa
iret
.global IntHandlerException3
IntHandlerException3:
pusha
pushf
cli
call IntHandlerException3C
popf
popa
iret
.global IntHandlerException4
IntHandlerException4:
pusha
pushf
cli
call IntHandlerException4C
popf
popa
iret
.global IntHandlerException5
IntHandlerException5:
pusha
pushf
cli
call IntHandlerException5C
popf
popa
iret
.global IntHandlerException6
IntHandlerException6:
pusha
pushf
cli
call IntHandlerException6C
popf
popa
iret
.global IntHandlerException7
IntHandlerException7:
pusha
pushf
cli
call IntHandlerException7C
popf
popa
iret
.global IntHandlerException8
IntHandlerException8:
pusha
pushf
cli
call IntHandlerException8C
popf
popa
iret
.global IntHandlerException9
IntHandlerException9:
pusha
pushf
cli
call IntHandlerException9C
popf
popa
iret
.global IntHandlerExceptionA
IntHandlerExceptionA:
pusha
pushf
cli
call IntHandlerExceptionAC
popf
popa
iret
.global IntHandlerExceptionB
IntHandlerExceptionB:
pusha
pushf
cli
call IntHandlerExceptionBC
popf
popa
iret
.global IntHandlerExceptionC
IntHandlerExceptionC:
pusha
pushf
cli
call IntHandlerExceptionCC
popf
popa
iret
.global IntHandlerExceptionD
IntHandlerExceptionD:
pusha
pushf
cli
call IntHandlerExceptionDC
popf
popa
iret
.global IntHandlerExceptionE
IntHandlerExceptionE:
pusha
pushf
cli
call IntHandlerExceptionEC
popf
popa
iret
.global IntHandlerExceptionF
IntHandlerExceptionF:
pusha
pushf
cli
call IntHandlerExceptionFC
popf
popa
iret
.global IntHandlerException10
IntHandlerException10:
pusha
pushf
cli
call IntHandlerException10C
popf
popa
iret

View file

@ -1,240 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/*
* Redesigned icon menu, allowing icons to be added/removed at runtime.
* 02/10/04 - David Pye dmp@davidmpye.dyndns.org
* You should not need to edit this file in normal circumstances - icons are
* added/removed via boot/IconMenuInit.c
*/
#include "boot.h"
#include "video.h"
#include "memory_layout.h"
#include <shared.h>
#include <filesys.h>
#include "rc4.h"
#include "sha1.h"
#include "BootFATX.h"
#include "xbox.h"
#include "BootFlash.h"
#include "cpu.h"
#include "BootIde.h"
#include "MenuActions.h"
#include "config.h"
#include "IconMenu.h"
#define TRANSPARENTNESS 0x30
#define SELECTED 0xff
typedef struct tagICONMENU {
PICON firstIcon;
PICON selectedIcon;
PICON firstVisibleIcon;
} ICONMENU;
PICONMENU CreateIconMenu(void) {
PICONMENU Menu;
Menu = (PICONMENU)malloc(sizeof(ICONMENU));
if (NULL != Menu) {
Menu->firstIcon = 0l;
Menu->selectedIcon = 0l;
Menu->firstVisibleIcon = 0l;
}
return Menu;
}
void AddIcon(PICONMENU Menu, PICON newIcon, bool Default) {
PICON iconPtr = Menu->firstIcon;
PICON currentIcon = 0l;
while (iconPtr != 0l) {
currentIcon = iconPtr;
iconPtr = iconPtr->nextIcon;
}
if (currentIcon==0l) {
//This is the first icon in the chain
Menu->firstIcon = newIcon;
}
//Append to the end of the chain
else currentIcon->nextIcon = newIcon;
iconPtr = newIcon;
iconPtr->nextIcon = 0l;
iconPtr->previousIcon = currentIcon;
if (Default) {
Menu->selectedIcon = newIcon;
}
}
static void IconMenuDraw(PICONMENU Menu, int nXOffset, int nYOffset) {
PICON iconPtr;
int iconcount;
if (Menu->firstVisibleIcon==0l) Menu->firstVisibleIcon = Menu->firstIcon;
if (Menu->selectedIcon==0l) Menu->selectedIcon = Menu->firstIcon;
iconPtr = Menu->firstVisibleIcon;
//There are max four 'bays' for displaying icons in - we only draw the four.
for (iconcount=0; iconcount<4; iconcount++) {
BYTE opaqueness;
if (iconPtr==0l) {
//No more icons to draw
return;
}
if (iconPtr==Menu->selectedIcon) {
//Selected icon has less transparency
//and has a caption drawn underneath it
opaqueness = SELECTED;
VIDEO_CURSOR_POSX=nXOffset+112*(iconcount+1)*4;
VIDEO_CURSOR_POSY=nYOffset+20;
VIDEO_ATTR=0xffffff;
printk("%s\n",iconPtr->szCaption);
}
else opaqueness = TRANSPARENTNESS;
BootVideoJpegBlitBlend(
(BYTE *)(FB_START+((vmode.width * (nYOffset-74))+nXOffset+(112*(iconcount+1))) * 4),
vmode.width, // dest bytes per line
&jpegBackdrop, // source jpeg object
(BYTE *)(jpegBackdrop.pData+(iconPtr->iconSlot * jpegBackdrop.bpp)),
0xff00ff|(((DWORD)opaqueness)<<24),
(BYTE *)(jpegBackdrop.pBackdrop + ((jpegBackdrop.width * (nYOffset-74)) + nXOffset+(112*(iconcount+1))) * jpegBackdrop.bpp),
ICON_WIDTH, ICON_HEIGHT
);
iconPtr = iconPtr->nextIcon;
}
}
void DisplayIconMenu(PICONMENU Menu, bool AllowExit) {
unsigned char *videosavepage;
DWORD COUNT_start;
DWORD temp=1;
PICON iconPtr=0l;
extern int nTempCursorMbrX, nTempCursorMbrY;
int nTempCursorResumeX, nTempCursorResumeY ;
int nTempCursorX, nTempCursorY;
int nModeDependentOffset=(vmode.width-640)/2;
nTempCursorResumeX=nTempCursorMbrX;
nTempCursorResumeY=nTempCursorMbrY;
nTempCursorX=VIDEO_CURSOR_POSX;
nTempCursorY=vmode.height-80;
// We save the complete framebuffer to memory (we restore at exit)
videosavepage = malloc(FB_SIZE);
memcpy(videosavepage,(void*)FB_START,FB_SIZE);
VIDEO_CURSOR_POSX=((252+nModeDependentOffset)<<2);
VIDEO_CURSOR_POSY=nTempCursorY-100;
VIDEO_ATTR=0xffc8c8c8;
printk("Select from Menu\n");
VIDEO_ATTR=0xffffffff;
IconMenuDraw(Menu, nModeDependentOffset, nTempCursorY);
COUNT_start = IoInputDword(0x8008);
//Main menu event loop.
while(1)
{
int changed=0;
USBGetEvents();
if (risefall_xpad_BUTTON(TRIGGER_XPAD_PAD_RIGHT) == 1)
{
if (Menu->selectedIcon->nextIcon!=0l) {
//A bit ugly, but need to find the last visible icon, and see if
//we are moving further right from it.
PICON lastVisibleIcon=Menu->firstVisibleIcon;
int i=0;
for (i=0; i<3; i++) {
if (lastVisibleIcon->nextIcon==0l) break;
lastVisibleIcon = lastVisibleIcon->nextIcon;
}
if (Menu->selectedIcon == lastVisibleIcon) {
//We are moving further right, so slide all the icons along.
Menu->firstVisibleIcon = Menu->firstVisibleIcon->nextIcon;
//As all the icons have moved, we need to refresh the entire page.
memcpy((void*)FB_START,videosavepage,FB_SIZE);
}
Menu->selectedIcon = Menu->selectedIcon->nextIcon;
changed=1;
}
temp=0;
}
else if (risefall_xpad_BUTTON(TRIGGER_XPAD_PAD_LEFT) == 1)
{
if (Menu->selectedIcon->previousIcon!=0l) {
if (Menu->selectedIcon == Menu->firstVisibleIcon) {
//We are moving further left, so slide all the icons along.
Menu->firstVisibleIcon = Menu->selectedIcon->previousIcon;
//As all the icons have moved, we need to refresh the entire page.
memcpy((void*)FB_START,videosavepage,FB_SIZE);
}
Menu->selectedIcon = Menu->selectedIcon->previousIcon;
changed=1;
}
temp=0;
}
//If anybody has toggled the xpad left/right, disable the timeout.
if (temp!=0) {
temp = IoInputDword(0x8008) - COUNT_start;
}
if ((risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_A) == 1) || (DWORD)(temp>(0x369E99*BOOT_TIMEWAIT))) {
memcpy((void*)FB_START,videosavepage,FB_SIZE);
free(videosavepage);
VIDEO_CURSOR_POSX=nTempCursorResumeX;
VIDEO_CURSOR_POSY=nTempCursorResumeY;
//Icon selected - invoke function pointer.
if (Menu->selectedIcon->functionPtr!=0l)
Menu->selectedIcon->functionPtr(Menu->selectedIcon->functionDataPtr);
//Shouldn't usually come back but at least if we do, the menu can
//continue to work.
//Setting changed means the icon menu will redraw itself.
changed=1;
videosavepage = malloc(FB_SIZE);
memcpy(videosavepage,(void*)FB_START,FB_SIZE);
temp = 0;
}
if (AllowExit && (risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_B) == 1)) {
memcpy((void*)FB_START,videosavepage,FB_SIZE);
free(videosavepage);
VIDEO_CURSOR_POSX=nTempCursorResumeX;
VIDEO_CURSOR_POSY=nTempCursorResumeY;
return;
}
if (changed) {
BootVideoClearScreen(&jpegBackdrop, nTempCursorY, VIDEO_CURSOR_POSY+1);
IconMenuDraw(Menu, nModeDependentOffset, nTempCursorY);
changed=0;
}
}
}
void DestroyIconMenu(PICONMENU Menu) {
PICON current;
PICON next;
current = Menu->firstIcon;
while (NULL != current) {
next = current->nextIcon;
free(current);
current = next;
}
free(Menu);
}

View file

@ -1,47 +0,0 @@
#ifndef _ICONMENU_H_
#define _ICONMENU_H_
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#define ICON_SOURCE_SLOT0 0
#define ICON_SOURCE_SLOT1 ICON_WIDTH
#define ICON_SOURCE_SLOT2 ICON_WIDTH*2
#define ICON_SOURCE_SLOT3 ICON_WIDTH*3
#define ICON_SOURCE_SLOT4 ICON_WIDTH*4
#define ICON_SOURCE_SLOT5 ICON_WIDTH*5
#define ICON_SOURCE_SLOT6 ICON_WIDTH*6
#define ICON_SOURCE_SLOT7 ICON_WIDTH*7
#define ICON_SOURCE_SLOT8 ICON_WIDTH*8
typedef struct tagICON *PICON;
typedef struct tagICON {
int iconSlot;
char *szCaption;
void (*functionPtr) (void *);
void *functionDataPtr;
PICON previousIcon;
PICON nextIcon;
} ICON;
typedef struct tagICONMENU *PICONMENU;
/* Create a new icon menu */
PICONMENU CreateIconMenu(void);
//Adds a new icon into the menu - they are displayed in the order added.
void AddIcon(PICONMENU Menu, PICON Icon, bool Default);
//This draws and handles input for the main menu
void DisplayIconMenu(PICONMENU Menu, bool AllowExit);
/* Destroy an icon menu */
void DestroyIconMenu(PICONMENU Menu);
#endif

View file

@ -1,616 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "boot.h"
#include "video.h"
#include "memory_layout.h"
#include <shared.h>
#include <filesys.h>
#include "rc4.h"
#include "sha1.h"
#include "BootFATX.h"
#include "xbox.h"
#include "BootFlash.h"
#include "cpu.h"
#include "BootIde.h"
#include "config.h"
static int nRet;
static DWORD dwKernelSize= 0, dwInitrdSize = 0;
int ExittoLinux(CONFIGENTRY *config);
void startLinux(void* initrdStart, unsigned long initrdSize, const char* appendLine);
void BootPrintConfig(CONFIGENTRY *config) {
int CharsProcessed=0, CharsSinceNewline=0, Length=0;
char c;
printk(" Bootconfig : Kernel %s \n", config->szKernel);
VIDEO_ATTR=0xffa8a8a8;
printk(" Bootconfig : Initrd %s \n", config->szInitrd);
VIDEO_ATTR=0xffa8a8a8;
printk(" Bootconfig : Appended arguments :\n");
Length=strlen(config->szAppend);
while (CharsProcessed<Length) {
c = config->szAppend[CharsProcessed];
CharsProcessed++;
CharsSinceNewline++;
if ((CharsSinceNewline>50 && c==' ') || CharsSinceNewline>65) {
printk("\n");
if (CharsSinceNewline>25) printk("%c",c);
CharsSinceNewline = 0;
}
else printk("%c",c);
}
printk("\n");
VIDEO_ATTR=0xffa8a8a8;
}
void memPlaceKernel(const BYTE* kernelOrg, DWORD kernelSize)
{
unsigned int nSizeHeader=((*(kernelOrg + 0x01f1))+1)*512;
memcpy((BYTE *)KERNEL_SETUP, kernelOrg, nSizeHeader);
memcpy((BYTE *)KERNEL_PM_CODE,(kernelOrg+nSizeHeader),kernelSize-nSizeHeader);
}
// if fJustTestingForPossible is true, returns 0 if this kind of boot not possible, 1 if it is worth trying
int BootLoadConfigNative(int nActivePartition, CONFIGENTRY *config, bool fJustTestingForPossible) {
DWORD dwConfigSize=0;
char *szGrub;
BYTE* tempBuf;
szGrub = (char *) malloc(265+4);
memset(szGrub,0,256+4);
memset((BYTE *)KERNEL_SETUP,0,2048);
szGrub[0]=0xff;
szGrub[1]=0xff;
szGrub[2]=nActivePartition;
szGrub[3]=0x00;
errnum=0;
boot_drive=0;
saved_drive=0;
saved_partition=0x0001ffff;
buf_drive=-1;
current_partition=0x0001ffff;
current_drive=0xff;
buf_drive=-1;
fsys_type = NUM_FSYS;
disk_read_hook=NULL;
disk_read_func=NULL;
VIDEO_ATTR=0xffa8a8a8;
//Try for /boot/linuxboot.cfg first
strcpy(&szGrub[4], "/boot/linuxboot.cfg");
nRet=grub_open(szGrub);
if(nRet!=1 || (errnum)) {
//Not found - try /linuxboot.cfg
errnum=0;
strcpy(&szGrub[4], "/linuxboot.cfg");
nRet=grub_open(szGrub);
}
dwConfigSize=filemax;
if (nRet!=1 || (errnum)) {
if(!fJustTestingForPossible) printk("linuxboot.cfg not found, using defaults\n");
} else {
int nLen;
if(fJustTestingForPossible) return 1; // if there's a linuxboot.cfg it must be worth trying to boot
nLen=grub_read((void *)KERNEL_SETUP, filemax);
if(nLen>0) { ((char *)KERNEL_SETUP)[nLen]='\0'; } // needed to terminate incoming string, reboot in ParseConfig without it
ParseConfig((char *)KERNEL_SETUP,config,&eeprom, NULL);
BootPrintConfig(config);
printf("linuxboot.cfg is %d bytes long.\n", dwConfigSize);
}
grub_close();
strncpy(&szGrub[4], config->szKernel,sizeof(config->szKernel));
nRet=grub_open(szGrub);
if(nRet!=1) {
if(fJustTestingForPossible) return 0;
printk("Unable to load kernel, Grub error %d\n", errnum);
while(1) ;
}
if(fJustTestingForPossible) return 1; // if there's a default kernel it must be worth trying to boot
// Use INITRD_START as temporary location for loading the Kernel
tempBuf = (BYTE*)INITRD_START;
dwKernelSize=grub_read(tempBuf, MAX_KERNEL_SIZE);
memPlaceKernel(tempBuf, dwKernelSize);
grub_close();
printk(" - %d bytes...\n", dwKernelSize);
if( (strncmp(config->szInitrd, "/no", strlen("/no")) != 0) && config->szInitrd[0]) {
VIDEO_ATTR=0xffd8d8d8;
printk(" Loading %s ", config->szInitrd);
VIDEO_ATTR=0xffa8a8a8;
strncpy(&szGrub[4], config->szInitrd,sizeof(config->szInitrd));
nRet=grub_open(szGrub);
if(filemax==0) {
printf("Empty file\n"); while(1);
}
if( (nRet!=1) || (errnum)) {
printk("Unable to load initrd, Grub error %d\n", errnum);
while(1) ;
}
printk(" - %d bytes\n", filemax);
dwInitrdSize=grub_read((void*)INITRD_START, MAX_INITRD_SIZE);
grub_close();
} else {
VIDEO_ATTR=0xffd8d8d8;
printk(" No initrd from config file");
VIDEO_ATTR=0xffa8a8a8;
dwInitrdSize=0;
}
free(szGrub);
return true;
}
#ifdef FLASH
int BootLoadFlashCD(void) {
DWORD dwConfigSize=0, dw;
int n;
int cdPresent=0;
int cdromId=0;
DWORD dwY=VIDEO_CURSOR_POSY;
DWORD dwX=VIDEO_CURSOR_POSX;
BYTE* tempBuf;
struct SHA1Context context;
unsigned char SHA1_result[20];
unsigned char checksum[20];
memset((BYTE *)KERNEL_SETUP,0,4096);
//See if we already have a CDROM in the drive
//Try for 4 seconds.
I2CTransmitWord(0x10, 0x0c01); // close DVD tray
for (n=0;n<16;++n) {
if((BootIso9660GetFile(cdromId,"/image.bin", (BYTE *)KERNEL_SETUP, 0x10)) >=0 ) {
cdPresent=1;
break;
}
wait_ms(250);
}
if (!cdPresent) {
//Needs to be changed for non-xbox drives, which don't have an eject line
//Need to send ATA eject command.
I2CTransmitWord(0x10, 0x0c00); // eject DVD tray
wait_ms(2000); // Wait for DVD to become responsive to inject command
VIDEO_ATTR=0xffeeeeff;
VIDEO_CURSOR_POSX=dwX;
VIDEO_CURSOR_POSY=dwY;
printk("Please insert CD with image.bin file on, and press Button A\n");
while(1) {
if (risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_A) == 1) {
I2CTransmitWord(0x10, 0x0c01); // close DVD tray
wait_ms(500);
break;
}
USBGetEvents();
wait_ms(10);
}
VIDEO_ATTR=0xffffffff;
// wait until the media is readable
while(1) {
if((BootIso9660GetFile(cdromId,"/image.bin", (BYTE *)KERNEL_SETUP, 0x10)) >=0 ) {
break;
}
wait_ms(200);
}
}
printk("CDROM: ");
printk("Loading bios image from CDROM:/image.bin. \n");
dwConfigSize=BootIso9660GetFile(cdromId,"/image.bin", (BYTE *)KERNEL_SETUP, 0x800);
dwConfigSize=BootIso9660GetFile("/IMAGE.BIN", (BYTE *)KERNEL_PM_CODE, 256*1024);
if( dwConfigSize < 0 ) { //It's not there
printk("image.bin not found on CDROM... Halting\n");
while(1) ;
}
printk("Image size: %i\n", dwConfigSize);
if (dwConfigSize!=256*1024) {
printk("Image is not a 256kB image\n");
while (1) ;
}
SHA1Reset(&context);
SHA1Input(&context,(BYTE *)KERNEL_PM_CODE,dwConfigSize);
SHA1Result(&context,SHA1_result);
memcpy(checksum,SHA1_result,20);
printk("Error code: $i\n", BootReflashAndReset((BYTE*) KERNEL_PM_CODE, (DWORD) 0, (DWORD) dwConfigSize));
SHA1Reset(&context);
SHA1Input(&context,(void *)LPCFlashadress,dwConfigSize);
SHA1Result(&context,SHA1_result);
if (memcmp(&checksum[0],&SHA1_result[0],20)==0) {
printk("Checksum in flash matching - Flash successful.\nYou should now reboot.");
while (1);
} else {
printk("Checksum in Flash not matching - MISTAKE -Reflashing!\n");
printk("Error code: %i\n", BootReflashAndReset((BYTE*) KERNEL_PM_CODE, (DWORD) 0, (DWORD) dwConfigSize));
}
}
#endif //Flash
int ExittoLinux(CONFIGENTRY *config) {
VIDEO_ATTR=0xff8888a8;
printk(" Kernel: %s\n", (char *)(0x00090200+(*((WORD *)0x9020e)) ));
printk("\n");
{
char *sz="\2Starting Linux\2";
VIDEO_CURSOR_POSX=((vmode.width-BootVideoGetStringTotalWidth(sz))/2)*4;
VIDEO_CURSOR_POSY=vmode.height-64;
VIDEO_ATTR=0xff9f9fbf;
printk(sz);
}
I2cSetFrontpanelLed(I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3 );
startLinux((void*)INITRD_START, dwInitrdSize, config->szAppend);
}
void startLinux(void* initrdStart, unsigned long initrdSize, const char* appendLine)
{
int nAta=0;
// turn off USB
BootStopUSB();
setup( (void *)KERNEL_SETUP, initrdStart, initrdSize, appendLine);
if(tsaHarddiskInfo[0].m_bCableConductors == 80) {
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&2) nAta=1;
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&4) nAta=2;
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&8) nAta=3;
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&16) nAta=4;
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&32) nAta=5;
} else {
// force the HDD into a good mode 0x40 ==UDMA | 2 == UDMA2
nAta=2; // best transfer mode without 80-pin cable
}
// nAta=1;
BootIdeSetTransferMode(0, 0x40 | nAta);
BootIdeSetTransferMode(1, 0x40 | nAta);
// orange, people seem to like that colour
I2cSetFrontpanelLed(
I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_GREEN2 | I2C_LED_GREEN3 |
I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3
);
// Set framebuffer address to final location (for vesafb driver)
(*(unsigned int*)0xFD600800) = (0xf0000000 | ((xbox_ram*0x100000) - FB_SIZE));
// disable interrupts
asm volatile ("cli\n");
// clear idt area
memset((void*)IDT_LOC,0x0,1024*8);
__asm __volatile__ (
"wbinvd\n"
// Flush the TLB
"xor %eax, %eax \n"
"mov %eax, %cr3 \n"
// Load IDT table (0xB0000 = IDT_LOC)
"lidt 0xB0000\n"
// DR6/DR7: Clear the debug registers
"xor %eax, %eax \n"
"mov %eax, %dr6 \n"
"mov %eax, %dr7 \n"
"mov %eax, %dr0 \n"
"mov %eax, %dr1 \n"
"mov %eax, %dr2 \n"
"mov %eax, %dr3 \n"
// Kill the LDT, if any
"xor %eax, %eax \n"
"lldt %ax \n"
// Reload CS as 0010 from the new GDT using a far jump
".byte 0xEA \n" // jmp far 0010:reload_cs
".long reload_cs_exit \n"
".word 0x0010 \n"
".align 16 \n"
"reload_cs_exit: \n"
// CS is now a valid entry in the GDT. Set SS, DS, and ES to valid
// descriptors, but clear FS and GS as they are not necessary.
// Set SS, DS, and ES to a data32 segment with maximum limit.
"movw $0x0018, %ax \n"
"mov %eax, %ss \n"
"mov %eax, %ds \n"
"mov %eax, %es \n"
// Clear FS and GS
"xor %eax, %eax \n"
"mov %eax, %fs \n"
"mov %eax, %gs \n"
// Set the stack pointer to give us a valid stack
"movl $0x03BFFFFC, %esp \n"
"xor %ebx, %ebx \n"
"xor %eax, %eax \n"
"xor %ecx, %ecx \n"
"xor %edx, %edx \n"
"xor %edi, %edi \n"
"movl $0x90000, %esi\n" // kernel setup area
"ljmp $0x10, $0x100000\n" // Jump to Kernel protected mode entry
);
// We are not longer here, we are already in the Linux loader, we never come back here
// See you again in Linux then
while(1);
}
bool LinuxPresentOnCD(int cdromId) {
return BootIso9660GetFile(cdromId,"/linuxboo.cfg", (BYTE *)KERNEL_SETUP, 0x800) >=0;
}
void BootLinuxFromCD(int cdromId)
{
DWORD dwConfigSize=0, dw;
int n;
DWORD dwY=VIDEO_CURSOR_POSY;
DWORD dwX=VIDEO_CURSOR_POSX;
BYTE* tempBuf;
CONFIGENTRY config;
memset((BYTE *)KERNEL_SETUP,0,4096);
printk("CDROM: ");
printk("Loading linuxboot.cfg from CDROM... \n");
dwConfigSize=BootIso9660GetFile(cdromId,"/linuxboo.cfg", (BYTE *)KERNEL_SETUP, 0x800);
if( dwConfigSize < 0 ) { // has to be there on CDROM
printk("linuxboot.cfg not found on CDROM... Halting\n");
while(1) ;
}
// LinuxBoot.cfg File Loaded
((char *)KERNEL_SETUP)[dwConfigSize]=0;
ParseConfig((char *)KERNEL_SETUP,&config,&eeprom, NULL);
BootPrintConfig(&config);
// Use INITRD_START as temporary location for loading the Kernel
tempBuf = (BYTE*)INITRD_START;
dwKernelSize=BootIso9660GetFile(cdromId,config.szKernel, tempBuf, MAX_KERNEL_SIZE);
if( dwKernelSize < 0 ) {
printk("Not Found, error %d\nHalting\n", dwKernelSize);
while(1);
} else {
memPlaceKernel(tempBuf, dwKernelSize);
printk(" - %d bytes...\n", dwKernelSize);
}
if( (strncmp(config.szInitrd, "/no", strlen("/no")) != 0) && config.szInitrd) {
VIDEO_ATTR=0xffd8d8d8;
printk(" Loading %s from CDROM", config.szInitrd);
VIDEO_ATTR=0xffa8a8a8;
dwInitrdSize=BootIso9660GetFile(cdromId,config.szInitrd, (void*)INITRD_START, MAX_INITRD_SIZE);
if( dwInitrdSize < 0 ) {
printk("Not Found, error %d\nHalting\n", dwInitrdSize);
while(1);
}
printk(" - %d bytes\n", dwInitrdSize);
} else {
VIDEO_ATTR=0xffd8d8d8;
printk(" No initrd from config file");
VIDEO_ATTR=0xffa8a8a8;
dwInitrdSize=0;
printk("");
}
ExittoLinux(&config);
}
bool LinuxPresentOnFATX(FATXPartition *partition) {
static int present = -1;
FATXFILEINFO fileinfo;
FATXFILEINFO infokernel;
int nConfig = 0;
BYTE *tempBuf;
CONFIGENTRY config;
bool partitionOpened;
if (0 <= present) {
return 0 != present;
}
if (NULL == partition) {
partition = OpenFATXPartition(0,SECTOR_STORE,STORE_SIZE);
if (NULL == partition) {
present = 0;
return false;
}
partitionOpened = true;
} else {
partitionOpened = false;
}
if(!LoadFATXFile(partition,"/linuxboot.cfg",&fileinfo)) {
if(LoadFATXFile(partition,"/debian/linuxboot.cfg",&fileinfo) ) {
fileinfo.buffer[fileinfo.fileSize]=0;
ParseConfig(fileinfo.buffer,&config,&eeprom,"/debian");
free(fileinfo.buffer);
}
} else {
fileinfo.buffer[fileinfo.fileSize]=0;
ParseConfig(fileinfo.buffer,&config,&eeprom,NULL);
free(fileinfo.buffer);
}
// Use INITRD_START as temporary location for loading the Kernel
tempBuf = (BYTE*)INITRD_START;
if(! LoadFATXFilefixed(partition,config.szKernel,&infokernel,tempBuf)) {
present = 0;
} else {
present = 1; // worth trying, since the filesystem and kernel exists
}
if (partitionOpened) {
CloseFATXPartition(partition);
}
return 0 != present;
}
void BootLinuxFromFATX(void)
{
static FATXPartition *partition = NULL;
static FATXFILEINFO fileinfo;
static FATXFILEINFO infokernel;
static FATXFILEINFO infoinitrd;
CONFIGENTRY config;
BYTE* tempBuf;
memset((BYTE *)KERNEL_SETUP,0,4096);
memset(&fileinfo,0x00,sizeof(fileinfo));
memset(&infokernel,0x00,sizeof(infokernel));
memset(&infoinitrd,0x00,sizeof(infoinitrd));
I2CTransmitWord(0x10, 0x0c01); // Close DVD tray
partition = OpenFATXPartition(0,
SECTOR_STORE,
STORE_SIZE);
if(partition == NULL) return;
printk("Loading linuxboot.cfg from FATX\n");
if(LoadFATXFile(partition,"/linuxboot.cfg",&fileinfo) ) {
wait_ms(50);
fileinfo.buffer[fileinfo.fileSize]=0;
ParseConfig(fileinfo.buffer,&config,&eeprom, NULL);
free(fileinfo.buffer);
}
else if(LoadFATXFile(partition,"/debian/linuxboot.cfg",&fileinfo) ) {
wait_ms(50);
fileinfo.buffer[fileinfo.fileSize]=0;
ParseConfig(fileinfo.buffer,&config,&eeprom, "/debian");
free(fileinfo.buffer);
} else {
wait_ms(50);
printk("linuxboot.cfg not found, using defaults\n");
}
BootPrintConfig(&config);
// Use INITRD_START as temporary location for loading the Kernel
tempBuf = (BYTE*)INITRD_START;
if(! LoadFATXFilefixed(partition,config.szKernel,&infokernel,tempBuf)) {
printk("Error loading kernel %s\n",config.szKernel);
while(1);
} else {
dwKernelSize = infokernel.fileSize;
// moving the kernel to its final location
memPlaceKernel(tempBuf, dwKernelSize);
printk(" - %d %d bytes...\n", dwKernelSize, infokernel.fileRead);
}
if( (strncmp(config.szInitrd, "/no", strlen("/no")) != 0) && config.szInitrd[0]) {
VIDEO_ATTR=0xffd8d8d8;
printk(" Loading %s from FATX", config.szInitrd);
wait_ms(50);
if(! LoadFATXFilefixed(partition,config.szInitrd,&infoinitrd, (void*)INITRD_START)) {
printk("Error loading initrd %s\n",config.szInitrd);
while(1);
}
dwInitrdSize = infoinitrd.fileSize;
printk(" - %d %d bytes\n", dwInitrdSize,infoinitrd.fileRead);
} else {
VIDEO_ATTR=0xffd8d8d8;
printk(" No initrd from config file");
VIDEO_ATTR=0xffa8a8a8;
dwInitrdSize=0;
printk("");
}
ExittoLinux(&config);
}
bool LinuxPresentOnNative(int partition) {
CONFIGENTRY config;
return BootLoadConfigNative(partition, &config, true);
}
//More grub bits
unsigned long saved_drive;
unsigned long saved_partition;
grub_error_t errnum;
unsigned long boot_drive;
extern unsigned long current_drive;
void BootLinuxFromNative(int partitionId) {
CONFIGENTRY config;
//This stuff is needed to keep the grub FS code happy.
char szGrub[256+4];
int menu=0,selected=0;
memset(szGrub,0x00,sizeof(szGrub));
szGrub[0]=0xff;
szGrub[1]=0xff;
szGrub[2]=partitionId;
szGrub[3]=0x00;
errnum=0;
boot_drive=0;
saved_drive=0;
saved_partition=0x0001ffff;
buf_drive=-1;
current_partition=0x0001ffff;
current_drive=0xff;
buf_drive=-1;
fsys_type = NUM_FSYS;
disk_read_hook=NULL;
disk_read_func=NULL;
BootLoadConfigNative(*(int*)partitionId,&config,false);
ExittoLinux(&config);
}
#ifdef ETHERBOOT
bool LinuxPresentOnEtherboot(void) {
return true;
}
void BootLinuxFromEtherboot(void) {
etherboot();
}
#endif

View file

@ -1,25 +0,0 @@
#ifndef _LOADLINUX_H_
#define _LOADLINUX_H_
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
bool LinuxPresentOnCD(int drive);
void BootLinuxFromCD(int drive);
bool LinuxPresentOnFATX(FATXPartition *partition);
void BootLinuxFromFATX(void);
bool LinuxPresentOnNative(int partition);
void BootLinuxFromNative(int partition);
bool LinuxPresentOnEtherboot(void);
void BootLinuxFromEtherboot(void);
#endif

View file

@ -1,373 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "boot.h"
#include "BootFATX.h"
#include "LoadReactOS.h"
#include "memory_layout.h"
static void startReactOS(void);
int ExittoReactOS(CONFIGENTRY *config) {
char *sz="\2Starting ReactOS\2";
VIDEO_CURSOR_POSX=((vmode.width-BootVideoGetStringTotalWidth(sz))/2)*4;
VIDEO_CURSOR_POSY=vmode.height-64;
VIDEO_ATTR=0xff9f9fbf;
printk(sz);
I2cSetFrontpanelLed(I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3 );
startReactOS();
}
static void startReactOS(void)
{
__asm __volatile__ (
// "ljmp $0x10, $0x90000\n"
"mov 0x8202, %eax\n"
"jmp %eax\n"
// "jmp 0x831f\n"
);
// We are not longer here, we are already in freeldr, we never come back here
// See you again in ReactOS then
while(1);
}
/* Length of area to be searched for multiboot header */
#define MULTIBOOT_SEARCHAREA_LEN 8192
/* The magic number for the Multiboot header. */
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
/* The Multiboot header. */
typedef struct tagMULTIBOOTHEADER {
u_int32_t magic;
u_int32_t flags;
u_int32_t checksum;
u_int32_t header_addr;
u_int32_t load_addr;
u_int32_t load_end_addr;
u_int32_t bss_end_addr;
u_int32_t entry_addr;
} MULTIBOOTHEADER, *PMULTIBOOTHEADER;
#define MB_INFO_FLAG_MEM_SIZE 0x00000001
#define MB_INFO_FLAG_BOOT_DEVICE 0x00000002
#define MB_INFO_FLAG_COMMAND_LINE 0x00000004
#define MB_INFO_FLAG_MODULES 0x00000008
#define MB_INFO_FLAG_AOUT_SYMS 0x00000010
#define MB_INFO_FLAG_ELF_SYMS 0x00000020
#define MB_INFO_FLAG_MEMORY_MAP 0x00000040
#define MB_INFO_FLAG_DRIVES 0x00000080
#define MB_INFO_FLAG_CONFIG_TABLE 0x00000100
#define MB_INFO_FLAG_BOOT_LOADER_NAME 0x00000200
#define MB_INFO_FLAG_APM_TABLE 0x00000400
#define MB_INFO_FLAG_GRAPHICS_TABLE 0x00000800
/* The symbol table for a.out. */
typedef struct tagAOUTSYMBOLTABLE {
u_int32_t tabsize;
u_int32_t strsize;
u_int32_t addr;
u_int32_t reserved;
} AOUTSYMBOLTABLE, *PAOUTSYMBOLTABLE;
/* The section header table for ELF. */
typedef struct tagELFSECTIONHEADERTABLE {
u_int32_t num;
u_int32_t size;
u_int32_t addr;
u_int32_t shndx;
} ELFSECTIONHEADERTABLE, *PELFSECTIONHEADERTABLE;
/* The Multiboot information. */
typedef struct tagMULTIBOOTINFO
{
u_int32_t flags;
u_int32_t mem_lower;
u_int32_t mem_upper;
u_int32_t boot_device;
u_int32_t cmdline;
u_int32_t mods_count;
u_int32_t mods_addr;
union {
AOUTSYMBOLTABLE aout_sym;
ELFSECTIONHEADERTABLE elf_sec;
} u;
u_int32_t mmap_length;
u_int32_t mmap_addr;
u_int32_t drives_length;
u_int32_t drives_addr;
u_int32_t config_table;
u_int32_t boot_loader_name;
u_int32_t apm_table;
u_int32_t vbe_control_info;
u_int32_t vbe_mode_info;
u_int32_t vbe_mode;
u_int32_t vbe_interface_seg;
u_int32_t vbe_interface_off;
u_int32_t vbe_interface_len;
} MULTIBOOTINFO, *PMULTIBOOTINFO;
/* The memory map. Be careful that the offset 0 is base_addr_low
but no size. */
typedef struct tagMEMORYMAP {
u_int32_t size;
u_int32_t base_addr_low;
u_int32_t base_addr_high;
u_int32_t length_low;
u_int32_t length_high;
u_int32_t type;
} MEMORYMAP, *PMEMORYMAP;
static void BootReactOS(BYTE *buffer, u_int32_t bootDevice)
{
PMULTIBOOTHEADER mbHeader;
PMULTIBOOTINFO mbInfo;
PMEMORYMAP mmap;
int nAta;
char *sz="\2Starting ReactOS\2";
VIDEO_CURSOR_POSX=((vmode.width-BootVideoGetStringTotalWidth(sz))/2)*4;
VIDEO_CURSOR_POSY=vmode.height-64;
VIDEO_ATTR=0xff9f9fbf;
printk(sz);
for (mbHeader = (PMULTIBOOTHEADER) buffer;
(BYTE *) mbHeader - buffer < MULTIBOOT_SEARCHAREA_LEN;
mbHeader = (PMULTIBOOTHEADER) ((BYTE *) mbHeader + 4)) {
if (MULTIBOOT_HEADER_MAGIC == mbHeader->magic &&
0 == mbHeader->magic + mbHeader->flags + mbHeader->checksum) {
break;
}
}
if (MULTIBOOT_SEARCHAREA_LEN <= (BYTE *) mbHeader - buffer) {
printk("No multiboot header found\n");
return;
}
/* Prepare to move freeldr to its final destination. Since that might
* involve overwriting cromwell structures we shutdown as much as
* possible. After this point, we can't return anymore */
BootStopUSB();
if(80 == tsaHarddiskInfo[0].m_bCableConductors) {
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&2) nAta=1;
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&4) nAta=2;
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&8) nAta=3;
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&16) nAta=4;
if(tsaHarddiskInfo[0].m_wAtaRevisionSupported&32) nAta=5;
} else {
/* force the HDD into a good mode 0x40 ==UDMA | 2 == UDMA2 */
nAta=2; /* best transfer mode without 80-pin cable */
}
BootIdeSetTransferMode(0, 0x40 | nAta);
BootIdeSetTransferMode(1, 0x40 | nAta);
/* orange, people seem to like that colour */
I2cSetFrontpanelLed(
I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_GREEN2 | I2C_LED_GREEN3 |
I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3
);
/* disable interrupts */
__asm__ __volatile__("cli\n");
/* clear idt area */
memset((void*)IDT_LOC,0x0,1024*8);
__asm__ __volatile__ (
"wbinvd\n"
/* Flush the TLB */
"xor %eax, %eax \n"
"mov %eax, %cr3 \n"
/* Load IDT table (0xB0000 = IDT_LOC) */
"lidt 0xB0000\n"
/* DR6/DR7: Clear the debug registers */
"xor %eax, %eax \n"
"mov %eax, %dr6 \n"
"mov %eax, %dr7 \n"
"mov %eax, %dr0 \n"
"mov %eax, %dr1 \n"
"mov %eax, %dr2 \n"
"mov %eax, %dr3 \n"
/* Kill the LDT, if any */
"xor %eax, %eax \n"
"lldt %ax \n"
/* Reload CS as 0010 from the new GDT using a far jump */
"ljmp $0x0010,$reload_cs_exit \n"
".align 16 \n"
"reload_cs_exit: \n"
/* CS is now a valid entry in the GDT. Set the other segment registers
* to valid descriptors (4Gb flat mode) as required by the multiboot
* spec */
"movw $0x0018, %ax \n"
"mov %eax, %ss \n"
"mov %eax, %ds \n"
"mov %eax, %es \n"
"mov %eax, %fs \n"
"mov %eax, %gs \n"
/* Set the stack pointer to give us a valid stack */
"movl $0x03BFFFFC, %esp \n"
);
/* Ok, preparations are complete. Now move the image */
memcpy((BYTE *) mbHeader->load_addr,
(BYTE *) mbHeader - (mbHeader->header_addr - mbHeader->load_addr),
mbHeader->load_end_addr - mbHeader->load_addr);
memset((BYTE *) mbHeader->load_end_addr, 0x00, mbHeader->bss_end_addr - mbHeader->load_end_addr);
/* Set up the multiboot info structure */
mbInfo = (PMULTIBOOTINFO) ((mbHeader->bss_end_addr + 3) & ~ 0x3);
memset(mbInfo, 0x00, sizeof(MULTIBOOTINFO));
mbInfo->flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE |
MB_INFO_FLAG_MEMORY_MAP;
/* Multiboot spec says mem_lower can't be larger than 640, which is
* true for a PC. ince we're bending the multiboot rules anyway
* let's pass the full megabyte */
mbInfo->mem_lower = 1024;
mbInfo->mem_upper = (xbox_ram - 1) * 1024;
mbInfo->boot_device = bootDevice;
mbInfo->mmap_length = 2 * sizeof(MEMORYMAP);
mmap = (PMEMORYMAP)(mbInfo + 1);
mbInfo->mmap_addr = (u_int32_t) mmap + sizeof(u_int32_t);
/* Normal RAM */
mmap->size = sizeof(MEMORYMAP);
mmap->base_addr_low = 0;
mmap->base_addr_high = 0;
mmap->length_low = (xbox_ram - 4) * 1024 * 1024;
mmap->length_high = 0;
mmap->type = 1;
/* Video RAM */
mmap++;
mmap->size = sizeof(MEMORYMAP);
mmap->base_addr_low = (xbox_ram - 4) * 1024 * 1024;
mmap->base_addr_high = 0;
mmap->length_low = 4 * 1024 * 1024;
mmap->length_high = 0;
mmap->type = 0;
/* Now setup the registers and jump to the multiboot entry point */
__asm__ __volatile__ (
"xorl %%ecx,%%ecx \n"
"xorl %%edx,%%edx \n"
"xorl %%esi,%%esi \n"
"xorl %%edi,%%edi \n"
"pushl %%eax \n"
"movl $0x2badb002,%%eax \n"
"ret \n"
: : "b" (mbInfo), "a" (mbHeader->entry_addr));
/* We should never return here, but if we do there's not much we can
* do besides sitting around idly */
while (1);
}
#define LOAD_AREA ((BYTE *) 0x00001000)
#define FATX_BOOTDEVICE 0x8000ffff /* drive 0x80, partition 0 */
#define CD_BOOTDEVICE 0x9f00ffff /* drive 0x9f is used by most BIOSes
for CDROM */
bool ReactOSPresentOnCD(int cdromId) {
return BootIso9660GetFile(cdromId,"/loader/setupldr.sys", LOAD_AREA, 0x80000) >=0;
}
void BootReactOSFromCD(int cdromId)
{
if (BootIso9660GetFile(cdromId,"/loader/setupldr.sys", LOAD_AREA, 0x80000) < 0) {
printk("Unable to load setupldr\n");
return;
}
BootReactOS(LOAD_AREA, CD_BOOTDEVICE);
}
bool ReactOSPresentOnFATX(FATXPartition *partition) {
static int present = -1;
FATXFILEINFO fileinfo;
bool partitionOpened;
if (0 <= present) {
return 0 != present;
}
if (NULL == partition) {
partition = OpenFATXPartition(0,SECTOR_STORE,STORE_SIZE);
if (NULL == partition) {
present = 0;
return false;
}
partitionOpened = true;
} else {
partitionOpened = false;
}
if(! FATXFindFile(partition,"/freeldr.sys",FATX_ROOT_FAT_CLUSTER,&fileinfo)) {
present = 0;
} else {
present = 1;
}
if (partitionOpened) {
CloseFATXPartition(partition);
}
return 0 != present;
}
void BootReactOSFromFATX(void) {
FATXPartition *partition;
FATXFILEINFO fileinfo;
partition = OpenFATXPartition(0,SECTOR_STORE,STORE_SIZE);
if (NULL == partition) {
return;
}
memset(&fileinfo,0x00,sizeof(fileinfo));
if(! LoadFATXFilefixed(partition,"/freeldr.sys",&fileinfo, LOAD_AREA) ) {
CloseFATXPartition(partition);
return;
}
BootReactOS(fileinfo.buffer, FATX_BOOTDEVICE);
free(fileinfo.buffer);
}
/* ReactOS on native partitions not supported yet */
bool ReactOSPresentOnNative(int partition) {
return false;
}
void BootReactOSFromNative(int partition) {
printk("Can't boot ReactOS from native HDD yet\n");
}
#ifdef ETHERBOOT
/* ReactOS on Etherboot not supported yet */
bool ReactOSPresentOnEtherboot(void) {
return false;
}
void BootReactOSFromEtherboot(void) {
printk("Can't boot ReactOS from network yet\n");
}
#endif

View file

@ -1,25 +0,0 @@
#ifndef _LOADREACTOS_H_
#define _LOADREACTOS_H_
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
bool ReactOSPresentOnCD(int drive);
void BootReactOSFromCD(int drive);
bool ReactOSPresentOnFATX(FATXPartition *partition);
void BootReactOSFromFATX(void);
bool ReactOSPresentOnNative(int partition);
void BootReactOSFromNative(int partition);
bool ReactOSPresentOnEtherboot(void);
void BootReactOSFromEtherboot(void);
#endif

View file

@ -1,5 +0,0 @@
EXTRA_CFLAGS := -I$(TOPDIR)/fs/grub -I$(TOPDIR)/fs/fatx -I$(TOPDIR)/lib/crypt -I$(TOPDIR)/drivers/flash -I$(TOPDIR)/drivers/cpu -I$(TOPDIR)/drivers/ide
O_TARGET := IconMenu.o TextMenu.o TextMenuInit.o MenuActions.o LoadLinux.o LoadReactOS.o BootStartup.o BootResetAction.o BootFromDevice.o
include $(TOPDIR)/Rules.make

View file

@ -1,45 +0,0 @@
Memory Mapping C/X romwell
0x0000 0000 -> free ?
0x0009 0000 Kernel info header start
0x0009 05FF Kernel info header end
0x0009 0800 Kernel command line start
0x0009 09ff Kernel command line end
0x000a 0000 Kernel / cromwell GDT Table
0x000B 0000 Kernel / cromwell IDT Table
0x0010 0000 Compressed Kernel ( max size = 8 MB)
0x008F FFFF Compressed Kernel end
0x0090 0000 Linux Ramdisk Starting address (max size = 33 MB)
0x029F FFFF Linux Ramdisk End address
0x02A0 0000 Memory manager for Cromwell (0x1000000 size = 16 MB)
0x039F FFFF Memory manager end
0x03A0 0000 c/x romwell Ramcopy Start (max size = 1MB)
0x03AF FFFF c/x romwell Ramcopy End
0x03C0 0000 c/x romwell Stackpointer upper limit
0x03C0 0000 Video Memory Start (4MB)
0x03FF FFFF Video Memory End
0x0400 0000 Physical Ram End
0xFFF0 0000 Flash Copy(0) Start
0xFFF3 FFFF Flash Copy(0) End
0xFFF4 0000 Flash Copy(1) Start
0xFFF7 FFFF Flash Copy(1) End
0xFFF8 0000 Flash Copy(2) Start
0xFFFB FFFF Flash Copy(2) End
0xFFFC 0000 Flash Copy(3) Start
0xFFFF FFFF Flash Copy(3) End
hamtitampti & ed

View file

@ -1,182 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "boot.h"
#include "BootFATX.h"
#include "BootIde.h"
#include "BootFromDevice.h"
#include "IconMenu.h"
#include "LoadLinux.h"
#include "LoadReactOS.h"
#include "MenuActions.h"
#ifdef FLASH
void FlashBios(void *data) {
BootLoadFlashCD();
}
#endif
void MoveToTextMenu(void *nothing) {
TextMenuInit();
TextMenu();
}
void SetLEDColor(void *color) {
I2cSetFrontpanelLed(*(BYTE*)color);
}
static void InitCDIcons(PICONMENU Menu) {
int i=0;
PICON iconPtr=0l;
for (i=0; i<2; ++i) {
//Add the cdrom icon - if you have two cdroms, you'll get two icons!
if (tsaHarddiskInfo[i].m_fAtapi) {
char *driveName=malloc(sizeof(char)*14);
sprintf(driveName,"CD-ROM (hd%c)",i ? 'b':'a');
iconPtr = (PICON)malloc(sizeof(ICON));
iconPtr->iconSlot = ICON_SOURCE_SLOT2;
iconPtr->szCaption = driveName;
iconPtr->functionPtr = BootFromCD;
iconPtr->functionDataPtr = malloc(sizeof(int));
*(int*)iconPtr->functionDataPtr = i;
AddIcon(Menu, iconPtr, false);
}
}
}
static void InitFatXIcons(PICONMENU Menu) {
PICON iconPtr=0l;
BYTE ba[512];
memset(ba,0x00,512);
BootIdeReadSector(0, &ba[0], 3, 0, 512);
if (!strncmp("BRFR",&ba[0],4)) {
//Got a FATX formatted HDD
FATXPartition *partition = NULL;
partition = OpenFATXPartition(0,SECTOR_STORE,STORE_SIZE);
if (NULL != partition) {
if (LinuxPresentOnFATX(partition) ||
ReactOSPresentOnFATX(partition)) {
//We can load the config, so it's bootable.
iconPtr = (PICON)malloc(sizeof(ICON));
iconPtr->iconSlot = ICON_SOURCE_SLOT4;
iconPtr->szCaption = "FatX (E:)";
iconPtr->functionPtr = BootFromFATX;
iconPtr->functionDataPtr = NULL;
//If we have fatx, mark it as default.
//If there are natives, they'll take over shortly
AddIcon(Menu, iconPtr, true);
}
CloseFATXPartition(partition);
}
}
}
static void InitNativeIcons(PICONMENU Menu) {
PICON iconPtr=0l;
BYTE ba[512];
memset(ba,0x00,512);
//This needs enhancing to check multiple HDDs, and support multiple
//boot entries.
BootIdeReadSector(0, &ba[0], 0, 0, 512);
//Is there an MBR here?
if( (ba[0x1fe]==0x55) && (ba[0x1ff]==0xaa) ) {
volatile BYTE * pb;
int n=0, nPos=0;
(volatile BYTE *)pb=&ba[0x1be];
//Check the first four partitions (this isn't good enough!)
for (n=0; n<4; n++,pb+=16) {
//Is this partition bootable?
if(pb[0]&0x80) {
if (LinuxPresentOnNative(n) ||
ReactOSPresentOnNative(n)) {
//Got a partition with an OS on - lets add an icon for it
iconPtr = (PICON)malloc(sizeof(ICON));
iconPtr->iconSlot = ICON_SOURCE_SLOT1;
iconPtr->szCaption = "HDD";
iconPtr->functionPtr = BootFromNative;
iconPtr->functionDataPtr=malloc(sizeof(int));
*(int*)(iconPtr->functionDataPtr)=n;
//At the moment, the *LAST* native partition on disk will
//be the one selected as bootable by default.
AddIcon(Menu, iconPtr, true);
}
}
}
}
}
#ifdef ETHERBOOT
static void InitEtherbootIcons(PICONMENU Menu) {
PICON iconPtr=0l;
if (LinuxPresentOnEtherboot() ||
ReactOSPresentOnEtherboot()) {
iconPtr = (PICON)malloc(sizeof(ICON));
iconPtr->iconSlot = ICON_SOURCE_SLOT3;
iconPtr->szCaption = "Etherboot";
iconPtr->functionPtr = BootFromEtherboot;
AddIcon(Menu, iconPtr, false);
}
}
#endif
#ifdef FLASH
static void InitFlashIcons(PICONMENU Menu) {
PICON iconPtr=0l;
iconPtr = (PICON)malloc(sizeof(ICON));
iconPtr->iconSlot = ICON_SOURCE_SLOT0;
iconPtr->szCaption = "Flash Bios";
iconPtr->functionPtr = FlashBios;
AddIcon(Menu, iconPtr, false);
}
#endif
/* Uncomment this one to test the new text menu system.
static void InitTextMenuIcons(PICONMENU Menu) {
PICON iconPtr=0l;
iconPtr = (PICON)malloc(sizeof(ICON));
iconPtr->iconSlot = ICON_SOURCE_SLOT0;
iconPtr->szCaption = "Advanced";
iconPtr->functionPtr = MoveToTextMenu;
AddIcon(Menu, iconPtr, false);
}
*/
static void MainMenuInit(PICONMENU Menu) {
int i=0;
PICON iconPtr=0l;
InitCDIcons(Menu);
InitFatXIcons(Menu);
InitNativeIcons(Menu);
#ifdef ETHERBOOT
InitEtherbootIcons(Menu);
#endif
#ifdef FLASH
InitFlashIcons(Menu);
#endif
/* Uncomment this one to test the new text menu system.
InitTextMenuIcons(Menu);
*/
}
void MainMenu(void) {
PICONMENU Menu;
Menu = CreateIconMenu();
MainMenuInit(Menu);
DisplayIconMenu(Menu, false);
DestroyIconMenu(Menu);
}

View file

@ -1,18 +0,0 @@
#ifndef _MENUACTIONS_H_
#define _MENUACTIONS_H_
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
//For the text menu jump
void MoveToTextMenu(void *nothing);
void SetLEDColor(void *);
void MainMenu(void);
#endif

View file

@ -1,162 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "TextMenu.h"
void TextMenuDraw(void);
void TextMenuBack(void);
TEXTMENUITEM *firstVisibleMenuItem=0l;
TEXTMENUITEM *selectedMenuItem=0l;
TEXTMENU *firstMenu=0l;
TEXTMENU *currentMenu=0l;
unsigned char *textmenusavepage;
void TextMenuAddItem(TEXTMENU *menu, TEXTMENUITEM *newMenuItem) {
TEXTMENUITEM *menuItem = menu->firstMenuItem;
TEXTMENUITEM *currentMenuItem=0l;
while (menuItem != 0l) {
currentMenuItem = menuItem;
menuItem = (TEXTMENUITEM*)menuItem->nextMenuItem;
}
if (currentMenuItem==0l) {
//This is the first icon in the chain
menu->firstMenuItem = newMenuItem;
}
//Append to the end of the chain
else currentMenuItem->nextMenuItem = (struct TEXTMENUITEM*)newMenuItem;
newMenuItem->nextMenuItem = 0l;
newMenuItem->previousMenuItem = (struct TEXTMENUITEM*)currentMenuItem;
}
void TextMenuBack(void) {
currentMenu = (TEXTMENU*)currentMenu->parentMenu;
selectedMenuItem = currentMenu->firstMenuItem;
firstVisibleMenuItem = currentMenu->firstMenuItem;
memcpy((void*)FB_START,textmenusavepage,FB_SIZE);
TextMenuDraw();
}
void TextMenuDraw(void) {
TEXTMENUITEM *item=0l;
int menucount;
VIDEO_CURSOR_POSX=75;
VIDEO_CURSOR_POSY=125;
if (currentMenu==0l) currentMenu = firstMenu;
if (selectedMenuItem==0l) selectedMenuItem = currentMenu->firstMenuItem;
if (firstVisibleMenuItem==0l) firstVisibleMenuItem = currentMenu->firstMenuItem;
//Draw the menu title.
VIDEO_ATTR=0x000000;
printk("\2%s",currentMenu->szCaption);
VIDEO_CURSOR_POSY+=30;
//Draw the menu items
VIDEO_CURSOR_POSX=150;
item=firstVisibleMenuItem;
for (menucount=0; menucount<8; menucount++) {
if (item==0l) {
//No more menu items to draw
return;
}
//Selected item in red
if (item == selectedMenuItem) VIDEO_ATTR=0xff0000;
else VIDEO_ATTR=0xffffff;
//Font size 2=big.
printk("\n\2\t%s\n",item->szCaption);
item=(TEXTMENUITEM *)item->nextMenuItem;
}
}
void TextMenu(void) {
TEXTMENUITEM *itemPtr;
TEXTMENU *menuPtr;
//Back up the current framebuffer contents
textmenusavepage = malloc(FB_SIZE);
memcpy(textmenusavepage,(void*)FB_START,FB_SIZE);
TextMenuDraw();
//Main menu event loop.
while(1)
{
int changed=0;
USBGetEvents();
if (risefall_xpad_BUTTON(TRIGGER_XPAD_PAD_UP) == 1)
{
if (selectedMenuItem->previousMenuItem!=0l) {
if (selectedMenuItem == firstVisibleMenuItem) {
firstVisibleMenuItem = (TEXTMENUITEM *)selectedMenuItem->previousMenuItem;
memcpy((void*)FB_START,textmenusavepage,FB_SIZE);
}
selectedMenuItem=(TEXTMENUITEM*)selectedMenuItem->previousMenuItem;
changed=1;
}
}
else if (risefall_xpad_BUTTON(TRIGGER_XPAD_PAD_DOWN) == 1) {
if (selectedMenuItem->nextMenuItem!=0l) {
TEXTMENUITEM *lastVisibleMenuItem = firstVisibleMenuItem;
int i=0;
//8 menu items per page.
for (i=0; i<7; i++) {
if (lastVisibleMenuItem->nextMenuItem==0l) break;
lastVisibleMenuItem = (TEXTMENUITEM *)lastVisibleMenuItem->nextMenuItem;
}
if (selectedMenuItem == lastVisibleMenuItem) {
firstVisibleMenuItem = (TEXTMENUITEM *)firstVisibleMenuItem->nextMenuItem;
memcpy((void*)FB_START,textmenusavepage,FB_SIZE);
}
selectedMenuItem=(TEXTMENUITEM*)selectedMenuItem->nextMenuItem;
changed=1;
}
}
else if ((risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_A) == 1)) {
//Redraw the page as it was before the menu was displayed.
memcpy((void*)FB_START,textmenusavepage,FB_SIZE);
free(textmenusavepage);
//Menu item selected - invoke function pointer.
if (selectedMenuItem->functionPtr!=0l) selectedMenuItem->functionPtr(selectedMenuItem->functionDataPtr);
//Re-malloc these if the function pointer did return us to the menu.
textmenusavepage = malloc(FB_SIZE);
memcpy(textmenusavepage,(void*)FB_START,FB_SIZE);
//Display the childmenu, if this menu item has one.
if (selectedMenuItem->childMenu!=0l) {
currentMenu = (TEXTMENU*)selectedMenuItem->childMenu;
selectedMenuItem = currentMenu->firstMenuItem;
firstVisibleMenuItem = currentMenu->firstMenuItem;
}
changed=1;
}
else if ((risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_B) == 1)) {
//B button takes us back up a menu
if (currentMenu->parentMenu==0l) {
//If this is the top level menu, save and quit the text menu.
memcpy((void*)FB_START,textmenusavepage,FB_SIZE);
free(textmenusavepage);
return;
}
TextMenuBack();
}
if (changed) {
TextMenuDraw();
changed=0;
}
}
}

View file

@ -1,57 +0,0 @@
#ifndef _TEXTMENU_H_
#define _TEXTMENU_H_
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "boot.h"
#include "video.h"
#include "memory_layout.h"
#include <shared.h>
#include "BootFATX.h"
#include "xbox.h"
#include "BootFlash.h"
#include "cpu.h"
#include "BootIde.h"
#include "MenuActions.h"
#include "config.h"
void TextMenuDraw(void);
void TextMenuBack(void);
struct TEXTMENUITEM;
struct TEXTMENU;
typedef struct {
//Menu item text
char *szCaption;
//Pointer to function to run when menu item selected.
void (*functionPtr) (void *);
//Pointer data, 0l if none.
void *functionDataPtr;
//Child menu, if any, attached to this menu item
struct TEXTMENU *childMenu;
//Next / previous menu items within this menu
struct TEXTMENUITEM *previousMenuItem;
struct TEXTMENUITEM *nextMenuItem;
} TEXTMENUITEM;
typedef struct {
//Menu title e.g. "Main Menu"
char *szCaption;
//A pointer to the first item of the linked list of menuitems that
//make up this menu.
TEXTMENUITEM* firstMenuItem;
//If 0l, we're a top level menu, otherwise a "BACK" menu item will be created,
//which takes us back to the parent menu..
struct TEXTMENU* parentMenu;
} TEXTMENU;
extern TEXTMENU *firstMenu;
extern TEXTMENU *currentMenu;
#endif

View file

@ -1,84 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "include/boot.h"
#include "TextMenu.h"
void TextMenuInit(void) {
TEXTMENUITEM *itemPtr;
TEXTMENU *menuPtr;
//Create the root menu - MANDATORY
firstMenu = malloc(sizeof(TEXTMENU));
firstMenu->szCaption="Main Menu\n";
firstMenu->parentMenu=0l;
firstMenu->firstMenuItem=0l;
//Add the first Item
itemPtr = (TEXTMENUITEM*)malloc(sizeof(TEXTMENUITEM));
memset(itemPtr,0x00,sizeof(TEXTMENUITEM));
itemPtr->szCaption="HDD Tools";
TextMenuAddItem(firstMenu, itemPtr);
itemPtr = (TEXTMENUITEM*)malloc(sizeof(TEXTMENUITEM));
memset(itemPtr,0x00,sizeof(TEXTMENUITEM));
itemPtr->szCaption="Bios Flashing";
TextMenuAddItem(firstMenu, itemPtr);
itemPtr = (TEXTMENUITEM*)malloc(sizeof(TEXTMENUITEM));
memset(itemPtr,0x00,sizeof(TEXTMENUITEM));
itemPtr->szCaption="LED Colors";
TextMenuAddItem(firstMenu, itemPtr);
//Child menu
menuPtr = (TEXTMENU*)malloc(sizeof(TEXTMENU));
memset(menuPtr,0x00,sizeof(TEXTMENU));
menuPtr->szCaption="LED colors menu";
menuPtr->parentMenu=(struct TEXTMENU*)firstMenu;
//itemptr here points to the "LED Colors" menuitem of the parentmenu, so this child menu is
//attached to that.
itemPtr->childMenu = (struct TEXTMENU*)menuPtr;
itemPtr = (TEXTMENUITEM*)malloc(sizeof(TEXTMENUITEM));
memset(itemPtr,0x00,sizeof(TEXTMENUITEM));
itemPtr->szCaption="Red LED";
itemPtr->functionPtr=SetLEDColor;
itemPtr->functionDataPtr = malloc(sizeof(BYTE));
*(BYTE*)(itemPtr->functionDataPtr) = (I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3 );
TextMenuAddItem(menuPtr, itemPtr);
itemPtr = (TEXTMENUITEM*)malloc(sizeof(TEXTMENUITEM));
memset(itemPtr,0x00,sizeof(TEXTMENUITEM));
itemPtr->szCaption="Orange LED";
itemPtr->functionPtr=SetLEDColor;
itemPtr->functionDataPtr = malloc(sizeof(BYTE));
*(BYTE*)(itemPtr->functionDataPtr) = (
I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_GREEN2 | I2C_LED_GREEN3 |
I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3
);
TextMenuAddItem(menuPtr, itemPtr);
itemPtr = (TEXTMENUITEM*)malloc(sizeof(TEXTMENUITEM));
memset(itemPtr,0x00,sizeof(TEXTMENUITEM));
itemPtr->szCaption="Green LED";
itemPtr->functionPtr=SetLEDColor;
itemPtr->functionDataPtr = malloc(sizeof(BYTE));
*(BYTE*)(itemPtr->functionDataPtr) = (I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_GREEN2 | I2C_LED_GREEN3 );
TextMenuAddItem(menuPtr, itemPtr);
itemPtr = (TEXTMENUITEM*)malloc(sizeof(TEXTMENUITEM));
memset(itemPtr,0x00,sizeof(TEXTMENUITEM));
itemPtr->szCaption="Flashing LED";
itemPtr->functionPtr=SetLEDColor;
itemPtr->functionDataPtr = malloc(sizeof(BYTE));
*(BYTE*)(itemPtr->functionDataPtr) = (I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_RED1 | I2C_LED_RED2);
TextMenuAddItem(menuPtr, itemPtr);
}

View file

@ -1,348 +0,0 @@
# Class to handle Elf images
# Placed under GNU Public License by Ken Yap, December 2000
package Elf;
use strict;
use IO::Seekable;
use constant;
use constant TFTPBLOCKSIZE => 512;
# ELF magic header in first 4 bytes
use constant MAGIC => "\x7FELF";
# This is defined by the bootrom layout
use constant HEADERSIZE => 512;
# Size of ELF header
use constant ELF_HDR_LEN => 52;
# Type code
use constant ELFCLASS32 => 1;
# Byte order
use constant ELFDATA2LSB => 1;
# ELF version
use constant EV_CURRENT => 1;
# File type
use constant ET_EXEC => 2;
# Machine type
use constant EM_386 => 3;
# Size of each program header
use constant PROG_HDR_LEN => 32;
# Type of header
use constant PT_LOAD => 1;
use constant PT_NOTE => 4;
# Size of each section header (there is just one)
use constant SECT_HDR_LEN => 40;
# Note types
use constant EIN_PROGRAM_NAME => 0x00000001;
use constant EIN_PROGRAM_VERSION => 0x00000002;
use constant EIN_PROGRAM_CHECKSUM => 0x00000003;
sub new {
my $class = shift;
my $self = { };
$self->{libdir} = shift;
$self->{segdescs} = [];
$self->{offset} = 0; # cumulative offset from beginning of file
$self->{checksum} = 0; # cumulative checksum of the file
$self->{summed} = 0; # number of bytes checksummed
$self->{data} = ""; # string buffer containing the output file
bless $self, $class;
# $self->_initialize();
return $self;
}
sub add_pm_header ($$$$$)
{
my ($self, $vendorinfo, $headerseg, $bootaddr, $progreturns) = @_;
push(@{$self->{segdescs}}, pack('A4C4@16v2V5v6',
MAGIC, ELFCLASS32, ELFDATA2LSB, EV_CURRENT,
255, # embedded ABI
ET_EXEC, # e_type
EM_386, # e_machine
EV_CURRENT, # e_version
$bootaddr, # e_entry
ELF_HDR_LEN, # e_phoff
0, # e_shoff (come back and patch this)
($progreturns ? 0x8000000 : 0), # e_flags
ELF_HDR_LEN, # e_ehsize
PROG_HDR_LEN, # e_phentsize
0, # e_phnum (come back and patch this)
SECT_HDR_LEN, # e_shentsize
1, # e_shnum, one mandatory entry 0
0)); # e_shstrndx
$self->{offset} = HEADERSIZE;
}
sub compute_ip_checksum
{
my ($str) = @_;
my ($checksum, $i, $size, $shorts);
$checksum = 0;
$size = length($$str);
$shorts = $size >> 1;
# Perl has a fairly large loop overhead so a straight forward
# implementation of the ip checksum is intolerably slow.
# Instead we use the unpack checksum computation function,
# and sum 16bit little endian words into a 32bit number, on at
# most 64K of data at a time. This ensures we do not overflow
# the 32bit sum allowing carry wrap around to be implemented by
# hand.
for($i = 0; $i < $shorts; $i += 32768) {
$checksum += unpack("%32v32768", substr($$str, $i <<1, 65536));
while($checksum > 0xffff) {
$checksum = ($checksum & 0xffff) + ($checksum >> 16);
}
}
if ($size & 1) {
$checksum += unpack('C', substr($$str, -1, 1));
while($checksum > 0xffff) {
$checksum = ($checksum & 0xffff) + ($checksum >> 16);
}
}
$checksum = (~$checksum) & 0xFFFF;
return $checksum;
}
sub add_summed_data
{
my ($self, $str) = @_;
my $new_sum = compute_ip_checksum($str);
my $new = $new_sum;
my $sum = $self->{checksum};
my $checksum;
$sum = ~$sum & 0xFFFF;
$new = ~$new & 0xFFFF;
if ($self->{summed} & 1) {
$new = (($new >> 8) & 0xff) | (($new << 8) & 0xff00);
}
$checksum = $sum + $new;
if ($checksum > 0xFFFF) {
$checksum -= 0xFFFF;
}
$self->{checksum} = (~$checksum) & 0xFFFF;
$self->{summed} += length($$str);
print "$$str";
# $self->{data} .= $$str;
# print STDERR sprintf("sum: %02x %02x sz: %08x summed: %08x\n",
# $new_sum, $self->{checksum}, length($$str), $self->{summed});
}
# This should not get called as we don't cater for real mode calls but
# is here just in case
sub add_header ($$$$$)
{
my ($self, $vendorinfo, $headerseg, $bootseg, $bootoff) = @_;
$self->add_pm_header($vendorinfo, $headerseg, ($bootseg << 4) + $bootoff, 0);
}
sub roundup ($$)
{
# Round up to next multiple of $blocksize, assumes that it's a power of 2
my ($size, $blocksize) = @_;
# Default to TFTPBLOCKSIZE if not specified
$blocksize = TFTPBLOCKSIZE if (!defined($blocksize));
return ($size + $blocksize - 1) & ~($blocksize - 1);
}
# Grab N bytes from a file
sub peek_file ($$$$)
{
my ($self, $descriptor, $dataptr, $datalen) = @_;
my ($file, $fromoff, $status);
$file = $$descriptor{'file'} if exists $$descriptor{'file'};
$fromoff = $$descriptor{'fromoff'} if exists $$descriptor{'fromoff'};
return 0 if !defined($file) or !open(R, "$file");
binmode(R);
if (defined($fromoff)) {
return 0 if !seek(R, $fromoff, SEEK_SET);
}
# Read up to $datalen bytes
$status = read(R, $$dataptr, $datalen);
close(R);
return ($status);
}
# Add a segment descriptor from a file or a string
sub add_segment ($$$)
{
my ($self, $descriptor, $vendorinfo) = @_;
my ($file, $string, $segment, $len, $maxlen, $fromoff, $align,
$id, $end, $vilen);
$end = 0;
$file = $$descriptor{'file'} if exists $$descriptor{'file'};
$string = $$descriptor{'string'} if exists $$descriptor{'string'};
$segment = $$descriptor{'segment'} if exists $$descriptor{'segment'};
$len = $$descriptor{'len'} if exists $$descriptor{'len'};
$maxlen = $$descriptor{'maxlen'} if exists $$descriptor{'maxlen'};
$fromoff = $$descriptor{'fromoff'} if exists $$descriptor{'fromoff'};
$align = $$descriptor{'align'} if exists $$descriptor{'align'};
$id = $$descriptor{'id'} if exists $$descriptor{'id'};
$end = $$descriptor{'end'} if exists $$descriptor{'end'};
if (!defined($len)) {
if (defined($string)) {
$len = length($string);
} else {
if (defined($fromoff)) {
$len = (-s $file) - $fromoff;
} else {
$len = -s $file;
}
return 0 if !defined($len); # no such file
}
}
if (defined($align)) {
$len = &roundup($len, $align);
} else {
$len = &roundup($len);
}
$maxlen = $len if (!defined($maxlen));
push(@{$self->{segdescs}}, pack('V8',
PT_LOAD,
$self->{offset}, # p_offset
$segment << 4, # p_vaddr
$segment << 4, # p_paddr
$len, # p_filesz
$len, # p_memsz == p_filesz
7, # p_flags == rwx
TFTPBLOCKSIZE)); # p_align
$self->{offset} += $len;
return ($len); # assumes always > 0
}
sub pad_with_nulls ($$$)
{
my ($self, $i, $blocksize) = @_;
$blocksize = TFTPBLOCKSIZE if (!defined($blocksize));
# Pad with nulls to next block boundary
$i %= $blocksize;
if ($i != 0) {
# Nulls do not change the checksum
print "\0" x ($blocksize - $i);
# $self->{data} .= "\0" x ($blocksize - $i);
$self->{summed} += ($blocksize - $i);
}
}
# Copy data from file to stdout
sub copy_file ($$)
{
my ($self, $descriptor) = @_;
my ($i, $file, $fromoff, $align, $len, $seglen, $nread, $data, $status);
$file = $$descriptor{'file'} if exists $$descriptor{'file'};
$fromoff = $$descriptor{'fromoff'} if exists $$descriptor{'fromoff'};
$align = $$descriptor{'align'} if exists $$descriptor{'align'};
$len = $$descriptor{'len'} if exists $$descriptor{'len'};
return 0 if !open(R, "$file");
if (defined($fromoff)) {
return 0 if !seek(R, $fromoff, SEEK_SET);
$len = (-s $file) - $fromoff if !defined($len);
} else {
$len = -s $file if !defined($len);
}
binmode(R);
# Copy file in TFTPBLOCKSIZE chunks
$nread = 0;
while ($nread != $len) {
$status = read(R, $data, TFTPBLOCKSIZE);
last if (!defined($status) or $status == 0);
$self->add_summed_data(\$data);
$nread += $status;
}
close(R);
if (defined($align)) {
$self->pad_with_nulls($nread, $align);
} else {
$self->pad_with_nulls($nread);
}
return ($nread);
}
# Copy data from string to stdout
sub copy_string ($$)
{
my ($self, $descriptor) = @_;
my ($i, $string, $len, $align, $data);
$string = $$descriptor{'string'} if exists $$descriptor{'string'};
$len = $$descriptor{'len'} if exists $$descriptor{'len'};
$align = $$descriptor{'align'} if exists $$descriptor{'align'};
return 0 if !defined($string);
$len = length($string) if !defined($len);
$data = substr($string, 0, $len);
$self->add_summed_data(\$data);
defined($align) ? $self->pad_with_nulls($len, $align) : $self->pad_with_nulls($len);
return ($len);
}
sub dump_segments
{
my ($self) = @_;
my ($s, $nsegs, @segdescs);
# generate the note header
my $notes = pack('V3Z8S2',
8, # n_namesz
2, # n_descsz
EIN_PROGRAM_CHECKSUM, # n_type
"ELFBoot", # n_name
0, # n_desc (Initial checksum value)
0); # padding to a 4byte boundary
my $note_len = length($notes);
# Add the note header
push(@{$self->{segdescs}}, pack('V8',
PT_NOTE, # p_type
HEADERSIZE - $note_len, # p_offset
0, # p_vaddr
0, # p_paddr
$note_len, # p_filesz
0, # p_memsz == p_filesz
0, # p_flags
0)); # p_align
@segdescs = @{$self->{segdescs}};
$nsegs = $#segdescs; # number of program header entries
# fill in e_phnum
substr($segdescs[0], 44, 2) = pack('v', $nsegs);
# fill in e_shoff to point to a record after program headers
substr($segdescs[0], 32, 4) = pack('V',
ELF_HDR_LEN + PROG_HDR_LEN * $nsegs);
$self->{checksum} = 0;
$self->{summed} = 0;
while ($s = shift(@segdescs)) {
$self->add_summed_data(\$s);
}
# insert section header 0
# we just need to account for the length, the null fill
# will create the record we want
# warn if we have overflowed allocated header area
print STDERR "Warning, too many segments in file\n"
if ($self->{summed} > HEADERSIZE - SECT_HDR_LEN - $note_len);
print "\0" x (HEADERSIZE - $self->{summed});
# $self->{data} .= "\0" x (HEADERSIZE - $self->{summed});
# Write the note header;
seek(STDOUT, HEADERSIZE - $note_len, SEEK_SET) or die "Cannot seek to note header\n";
print "$notes";
# substr($self->{data}, HEADERSIZE - $note_len, $note_len) = $notes
}
sub finalise_image
{
my ($self) = @_;
# Fill in the checksum
seek(STDOUT, HEADERSIZE - 4, SEEK_SET) or die "Cannot seek to checksum\n";
print pack('S', $self->{checksum});
# substr($self->{data}, (HEADERSIZE - 4), 2) = pack('S', $self->{checksum});
# print $self->{data};
}
1;

View file

@ -1,4 +0,0 @@
O_TARGET := vml_Startup.o
include $(TOPDIR)/Rules.make

View file

@ -1,7 +0,0 @@
"ethboot" is a Cromwell image that can be used to chainload Cromwell
via Etherboot. This makes it easy to test out new Cromwell builds
without needing to burn them into flash memory.
"ethboot" can be used just like a kernel image, i.e. it needs to be copied to
your tftp directory and specified in the "filename" option of dhcpd.conf.
Select the Etherboot option in Cromwell and enjoy your new BIOS.

View file

@ -1,62 +0,0 @@
.code32
.section .vmlinuz_start, "ax"
.org 0x00
xor %eax, %eax
xor %edx, %edx
cld
mov $0x03A00000, %edi // Destiation
mov $0x00100100, %esi // Source
mov $0x200000, %ecx // 2MB
rep movsb
wbinvd
/*
mov $0xc004, %dx
mov $0x20, %al
out %al, %dx
mov $0xc008, %dx
mov $0x8, %al
out %al, %dx
mov $0xc006, %dx
mov $0xa6, %al
out %al, %dx
mov $0xc006, %dx
in %dx,%al
mov $0xc002, %dx
mov $0x1a, %al
out %al, %dx
mov $0xc000, %dx
ledspin: in %dx, %al
cmp $0x10, %al
jnz ledspin
mov $0xc004, %dx
mov $0x20, %al
out %al, %dx
mov $0xc008, %dx
mov $0x7, %al
out %al, %dx
mov $0xc006, %dx
mov $0x1, %al
out %al, %dx
mov $0xc006, %dx
in %dx,%al
mov $0xc002, %dx
mov $0x1a, %al
out %al, %dx
mov $0xc000, %dx
ledspin1: in %dx, %al
cmp $0x10, %al
jnz ledspin1
jmp ledspin1
*/
cld
ljmp $0x10, $0x03A00000
.org 0x0100 // append crom image here

View file

@ -1,58 +0,0 @@
/*
* loader script
*/
OUTPUT_FORMAT ("elf32-i386");
OUTPUT_ARCH(i386);
MEMORY
{
ram (rwx) : ORIGIN = 0, LENGTH = 64M
rom (rx) : ORIGIN = 0x03A00000, LENGTH = 2M
}
LOW_ROM = 0x00100000;
SECTIONS {
/* ROM allocations */
.vmlinuz_start LOW_ROM : AT ( 0 ){
*(.vmlinuz_start);
}
.rodata (LOW_ROM + SIZEOF(.vmlinuz_start)) : AT (SIZEOF(.vmlinuz_start)) {
*(.rodata);
*(.rodata.str1.1);
*(.rodata.str1.32);
*(.rodata.cst4);
*(.rodata.cst8);
}
/* ram allocations */
.data (LOW_ROM + SIZEOF(.vmlinuz_start) + SIZEOF(.rodata)) : AT( SIZEOF(.vmlinuz_start) + SIZEOF(.rodata) ) {
_start_data = .;
*(.data);
*(.sdata);
*(.sdata2);
*(.got);
_end_data = .;
}
/* the data (initialized globals) is moved to ram by the startup code */
.bss ( ADDR(.data) + SIZEOF(.data) ) : {
_bss = .;
*(.bss)
*(.sbss)
*(COMMON)
_ebss = . ;
_heap = . ;
}
}

View file

@ -1,671 +0,0 @@
#!/usr/bin/perl -w
# Program to create a netboot image for ROM/FreeDOS/DOS/Linux
# Placed under GNU Public License by Ken Yap, December 2000
# 2003.04.28 R. Main
# Tweaks to work with new first-dos.S for large disk images
BEGIN {
push(@INC, '@@LIBDIR@@');
}
use strict;
use Getopt::Long;
use IO::Seekable;
use Socket;
use Elf;
use constant;
use constant DEBUG => 0;
use constant LUA_VERSION => 0x04000100; # 4.0.1.0
use bytes;
use vars qw($libdir $version $format $target $output $module $relocseg $relocsegstr
$progreturns $param $append $rootdir $rootmode $ip $ramdisk $rdbase
$simhd $dishd $squashfd $first32 $showversion);
sub check_file
{
my ($f, $status);
$status = 1;
foreach $f (@_) {
if (!-e $f) {
print STDERR "$f: file not found\n";
$status = 0;
} elsif (!-f $f) {
print STDERR "$f: not a plain file\n";
$status = 0;
} elsif (!-r $f) {
print STDERR "$f: file not readable\n";
$status = 0;
}
}
return ($status);
}
sub mkelf_img ($)
{
my ($module) = @_;
my ($romdesc);
$#ARGV >= 0 or die "Usage: $0 .img-file\n";
return unless check_file($ARGV[0]);
$module->add_pm_header("mkelf-img-$version", $relocseg + 0x3E0, 0x100000, 0);
$romdesc = { file => $ARGV[0],
segment => 0x10000,
maxlen => 0x10000,
id => 20,
end => 1 };
$module->add_segment($romdesc);
$module->dump_segments();
$module->copy_file($romdesc);
}
$libdir = '@@LIBDIR@@'; # where config and auxiliary files are stored
$version = '@@VERSION@@';
$showversion = '';
$simhd = 0;
$dishd = 0;
$squashfd = 1;
$relocsegstr = '0x9000';
$progreturns = 0;
GetOptions('format=s' => \$format,
'target=s' => \$target,
'output=s' => \$output,
'param=s' => \$param,
'append=s' => \$append,
'rootdir=s' => \$rootdir,
'rootmode=s' => \$rootmode,
'ip=s' => \$ip,
'rdbase=s' => \$rdbase,
'harddisk!' => \$simhd,
'disableharddisk!' => \$dishd,
'squash!' => \$squashfd,
'first32:s' => \$first32,
'progreturns!' => \$progreturns,
'relocseg=s' => \$relocsegstr,
'version' => \$showversion);
if ($showversion) {
print STDERR "$version\n";
exit 0;
}
if (defined($ENV{LANG}) and $ENV{LANG} =~ /\.UTF-8$/i) {
print STDERR <<'EOF';
Warning: Perl 5.8 may have a bug that affects handing of strings in Unicode
locales that may cause misbehaviour with binary files. To work around this
problem, set $LANG to not have a suffix of .UTF-8 before running this program.
EOF
}
$format = "elf";
$target = "img";
if (!defined($format)) {
print STDERR "No format specified with program name or --format=\n";
exit 1;
}
if (!defined($target)) {
print STDERR "No target specified with program name or --target=\n";
exit 1;
}
if (defined($output)) {
die "$output: $!\n" unless open(STDOUT, ">$output");
}
binmode(STDOUT);
if ($format eq 'elf') {
$first32 = '' if !defined($first32);
$module = Elf->new($libdir);
die "Output must be file\n" unless (seek(STDOUT, 0, SEEK_SET));
} else {
die "Format $format not supported\n";
}
if ($relocsegstr eq '0x9000' or $relocsegstr eq '0x8000') {
$relocseg = hex($relocsegstr);
} else {
print STDERR "relocseg must be 0x9000 or 0x8000 only, setting to 0x9000\n";
$relocseg = 0x9000;
}
if ($target eq 'img') {
&mkelf_img($module);
} else {
print STDERR "Target $target not supported\n";
exit;
}
$module->finalise_image();
close(STDOUT);
exit 0;
__END__
=head1 NAME
mknbi - make network bootable image
=head1 SYNOPSIS
B<mknbi> --version
B<mknbi> --format=I<format> --target=I<target> [--output=I<outputfile>] I<target-specific-arguments>
B<mkelf-linux> [--output=I<outputfile>] I<kernelimage> [I<ramdisk>]
B<mknbi-linux> [--output=I<outputfile>] I<kernelimage> [I<ramdisk>]
B<mknbi-rom> [--output=I<outputfile>] I<.z?rom-file>
B<mkelf-img> [--output=I<outputfile>] I<.z?img-file>
B<mkelf-menu> [--output=I<outputfile>] [I<dataimage>]
B<mknbi-menu> [--output=I<outputfile>] [I<dataimage>]
B<mkelf-nfl> [--output=I<outputfile>] [I<dataimage>]
B<mknbi-nfl> [--output=I<outputfile>] [I<dataimage>]
B<mkelf-lua> [--output=I<outputfile>] I<luabin>
B<mknbi-fdos> [--output=I<outputfile>] I<kernel.sys floppyimage>
B<mknbi-dos> [--output=I<outputfile>] I<floppyimage>
=head1 DESCRIPTION
B<mknbi> is a program that makes network bootable images for various
operating systems suitable for network loading by Etherboot or Netboot,
which are ROM boot loaders. If you are looking to boot using PXE, look
no further, mknbi is not what you want. You probably want something like
PXELINUX which is part of the SYSLINUX package.
B<mknbi> --version prints the current version. Use this before reporting
problems.
B<mknbi> can be invoked with the B<--format> and B<--target> options or
links can be made to it under format and target specific names. E.g.
mkelf-linux is the same as mknbi --format=elf --target=linux.
B<--format>=I<format> Specify the format of the output. Currently
available are nbi and elf. ELF format only works with linux and menu.
Otherwise the invocation is the same as for mknbi. In discussions below,
the mknbi form is used.
B<--target>=I<target> Specify the target binary. Currently available are
linux, menu, rom, fdos and dos. B<mknbi> is not needed for booting
FreeBSD.
B<--output=>I<outputfile> Specify the output file, can be used with
all variants. Stdout is the default.
The package must be installed in the destination location before the
executables can be run, because it looks for library files.
Each of the variants will be described separately.
=head1 MKELF-LINUX
B<mkelf-linux> and B<mknbi-linux> makes a boot image from a Linux kernel
image, either a zImage or a bzImage.
=head1 MKELF-LINUX OPTIONS
B<--param=>I<string> Replace the default parameter string with the
specified one. This option overrides all the following options so you
should know what you are doing.
B<--append>=I<string> Appends the specified string to the existing
parameter string. This option operates after the other parameter options
have been evaluated.
B<--rootdir>=I<rootdir> Define name of directory to mount via NFS from
the boot server.
In the absence of this option, the default is to use the directory
C</tftpboot/>I<%s>, with the I<%s> representing the hostname or
IP-address of the booting system, depending on whether the hostname
attribute is present in the BOOTP/DHCP reply.
If C<rom> is given, and if the BOOTP/DHCP server is able to handle the RFC 1497
extensions, the value of the rootpath option is used as the root directory.
If the name given to the option starts with C</dev/>, the corresponding
device is used as the root device, and no NFS directory will be mounted.
B<--rootmode>=C<ro|rw> Defines whether the root device will be mounted
read-only or read-write respectively. Without this parameter, the
default is C<rw>.
B<--ip=>I<string> Define client and server IP addresses.
In the absence of this option no IP addresses are defined, and the
kernel will determine the IP addresses by itself, usually by using DHCP,
BOOTP or RARP. Note that the kernel's query is I<in addition to> the
query made by the bootrom, and requires the IP: kernel level
autoconfiguration (CONFIG_IP_PNP) feature to be included in the kernel.
Important note: In Linux kernels 2.2.x where x >= 18, and 2.4.x where x
>= 5, it is B<necessary> to specify one of the enabling options in the
next paragraph to cause the IP autoconfiguration to be activated.
Unlike in previous kernels, IP autoconfiguration does not happen by
default. Also note that IP autoconfiguration and NFSroot are likely to
go away in Linux 2.6 and that userspace IP configuration methods using
ramdisk and userspace DHCP daemons are preferred now.
If one of the following: C<off, none, on, any, dhcp, bootp, rarp, both>,
is given, then the option will be passed unmodified to the kernel and
cause that autoconfig option to be chosen.
If C<rom> is given as the argument to this option, all necessary IP
addresses for NFS root mounting will be inherited from the BOOTP/DHCP
answer the bootrom got from the server.
It's also possible to define the addresses during compilation of the boot
image. Then, all addresses must be separated by a colon, and ordered in
the following way:
C<--ip=>I<client:server:gateway:netmask:hostname[:dev[:proto]]>
Using this option B<mkelf-linux> will automatically convert system names
into decimal IP addresses for the first three entries in this string.
The B<hostname> entry will be used by the kernel to set the host name of
the booted Linux diskless client. When more than one network interface
is installed in the diskless client, it is possible to specify the name
of the interface to use for mounting the root directory via NFS by
giving the optional value C<dev>. This entry has to start with the
string C<eth> followed by a number from 0 to 9. However, if only one
interface is installed in the client, this I<dev> entry including the
preceding semicolon can be left out. The I<proto> argument is one of the
IP autoconfiguration enabling options listed above. (Author: it's not
clear to me what the IP autoconfiguration does when the parameters are
already specified. Perhaps it's to obtain parameters not specified,
e.g. NIS domain.)
B<--rdbase=>I<top|asis|0xNNNNNNNN> Set the ramdisk load address. C<top>
moves the ramdisk to the top of memory before jumping to the kernel.
This is the default if rdbase is not specified. This option requires
that first-linux's kernel sizing work correctly. C<asis> loads it at
0x100000 (1MB) if the kernel is loaded low; or leaves it just after the
kernel in memory, if the kernel is loaded high. For this option to work,
the kernel must be able to handle ramdisks at these addresses.
I<0xNNNNNNNN> moves the ramdisk to the hex address specified. The onus
is on the user to specify a suitable address that is acceptable to the
kernel and doesn't overlap with any other segments. It will have to be
aligned to a 4k byte boundary so you should ensure that this is so. (The
last three hex digits must be 0.)
B<--first32=>I<program> Override the default first stage setup
program. It can be used to call extensions to the Etherboot code, which
paves the way for additional useful functionality without enlarging the
size of the Etherboot footprint. --first32 is implied by the ELF
format.
B<--progreturns> This option is used in conjunction with and only valid
with the --first32 option to indicate to the Etherboot loader that the
called program will return to loader and hence Etherboot should not
disable the network device as is the case when the program will never
return to Etherboot.
B<--relocseg=>I<segaddr> This option is used to specify a relocation of
the Linux first, boot, setup, and parameter segments to another 64k
band. Currently the only valid values are 0x9000 and 0x8000,
corresponding to linear addresses of 0x90000 and 0x80000 upwards. The
default is 0x9000. Usually you use this option if you have relocated
Etherboot to 0x84000 to avoid other code in the 0x90000 segment like
DOC. The Linux kernel must support relocation which implies a 2.4 kernel
or later. --relocseg only works reliably with ELF or --first32=.
B<mem=>I<memsize> This is not a command line option but a kernel
parameter that is intercepted by the first32 stage and used as the top
of memory, to match Linux's interpretation. I<memsize> can be suffixed
by C<G> to indicate gibibytes (times 2^30), C<M> to indicate mebibytes
(times 2^20) or C<K> to indicate kibibytes (times 2^10). Note that the
suffixes are uppercase. This kernel parameter can be specified in
--append= or option-129 of the DHCP/BOOTP record.
Run the program thus:
mkelf-linux I<kernel-image> [I<ramdisk-image>] > linux.nb
Then move F<linux.nb> to where the network booting process expects to
find it.
=head1 MKELF-LINUX BOOTP/DHCP VENDOR TAGS
B<mkelf-linux> includes a startup code at the beginning of the Linux
kernel which is able to detect certain DHCP vendor defined options.
These can be used to modify the kernel loading process at runtime. To
use these options with ISC DHCPD v3, a popular DHCP daemon, the syntax
is as below. You will need to adjust the syntax for other DHCP or BOOTP
daemons.
option etherboot-signature code 128 = string;
option kernel-parameters code 129 = text;
...
option etherboot-signature E4:45:74:68:00:00;
option kernel-parameters "INITRD_DBG=6 NIC=3c509";
Option 128 is required to be the six byte signature above. See the
vendortags appendix of the Etherboot user manual for details.
The following option is presently supported by B<mkelf-linux>:
B<129> The I<string> value given with this option is appended verbatim to
the end of the kernel command line. It can be used to specify arguments
like I/O addresses or DMA channels required for special hardware
like SCSI adapters, network cards etc. Please consult the Linux kernel
documentation about the syntax required by those options. It is the same
as the B<--append> command line option to B<mkelf-linux>, but works at
boot time instead of image build time.
B<130> With this option it is possible to the select the network adapter
used for mounting root via NFS on a multihomed diskless client. The
syntax for the I<string> value is the same as for the C<dev> entry used
with the B<--ip=> option as described above. However note that the
B<mkelf-linux> runtime setup routine does not check the syntax of the
string.
=head1 MKNBI-ROM
B<mknbi-rom> makes a boot image from an Etherboot C<.rom> or C<.zrom>
boot ROM image. This allows it to be netbooted using an existing
ROM. This is useful for developing Etherboot drivers or to load a newer
version of Etherboot with an older one.
Run mknbi-rom like this:
mknbi-rom nic.zrom > nic.nb
Move F<nic.nb> to where the network booting process expects to find it.
The boot ROM will load this as the I<operating system> and execute the
ROM image.
=head1 MKELF-IMG
B<mkelf-img> makes a boot image from an Etherboot C<.img> or C<.zimg>
image. This allows it to be netbooted using an existing ROM. This is
useful for developing Etherboot drivers or to load a newer version of
Etherboot with an older one.
Run mkelf-img like this:
mkelf-img nic.zimg > nic.nb
Move F<nic.nb> to where the network booting process expects to find it.
The boot ROM will load this as the I<operating system> and execute the
image.
Note that this does not test the ROM loader portion that's in a C<.z?rom>
image, but not in a C<.z?img>.
=head1 MKELF-MENU
B<mkelf-menu> and B<mknbi-menu> make a boot image from an auxiliary menu
program. Etherboot has the ability to load an auxiliary program which
can interact with the user, modify the DHCP structure, and return a
status. Based on the status, Etherboot can load another binary, restart
or exit. This makes it possible to have elaborate user interface
programs without having to modify Etherboot. The specification for
auxiliary program is documented in the Etherboot Developer's Manual.
B<mkelf-menu> and B<mknbi-menu> take a binary named C<menu> from the
library directory, which is assumed to have an entry point of 0x60000.
An optional argument is accepted, and this is loaded at 0x80000. This
can be a data file used by the menu program.
Currently, the menu binary provided duplicates the builtin menu facility
of Etherboot with the exception of a couple of small differences: no
server or gateway specifications are used and nested TFTP loads don't
work. You should not have MOTD or IMAGE_MENU defined in your Etherboot
build to be able to use this external menu binary. The specifications of
the DHCP option required is in the vendortags document in the Etherboot
user manual.
Typical usage is like this:
mkelf-menu > menu.nb
Then put menu.nb in the TFTP boot directory and edit your DHCP options
according to the documentation.
Alternate user interface programs are highly encouraged.
=head1 MKELF-NFL
B<mkelf-nfl> and B<mknbi-nfl> make a boot image from the NFL menu
program. This menu program takes the names of images from a
menu-text-file file which just contains lines with the filenames
(relative to the tftpd root directory) of images to load. The
user-interface is a light-bar, similar to that used in GRUB. There is a
sample menu-text-file in C<menu-nfl.eg>. The special entry "Quit
Etherboot" (without quotes, of course) can be used in menu-text-files
as an entry that causes Etherboot to quit and return to the invoking
environment, which is the BIOS in the case of ROMs.
Typical usage is:
mkelf-nfl I<menu-text-file> > nfl.nb
Then put nfl.nb in the TFTP boot directory and specify as the boot
image. Chaining to other menus works.
Enhancements to the menu format accepted to specify other features such
as titles, timeout, colours, and so forth are highly encouraged.
=head1 MKELF-LUA
B<mkelf-lua> makes an ELF image from a precompiled Lua
(C<http://www.tecgraf.puc-rio.br/lua/>) program.
Typical usage is:
mkelf-lua hello.lb > luaprog.nb
where C<hello.lb> was generated from a Lua program by:
luac -o hello.lb hello.lua
The functions available to Lua programs in this environment is described
in a separate document.
=head1 MKNBI-FDOS
B<mknbi-fdos> makes a boot image from a FreeDOS kernel file and a floppy
image. Note that the kernel image is not read from the floppy section
of the boot image, but is a separate section in the boot image. The
bootloader has been adjusted to jump to it directly. This means the
space that would be taken up on the I<floppy> by the kernel image file
can now be used for applications and data.
Obtain a distribution of FreeDOS with a recent kernel, probably at least
2006. It has been tested with 2012 but nothing older. You can get the
FreeDOS kernel here:
C<http://freedos.sourceforge.net/>
Follow the instructions to make a bootable floppy. Then get an image
of the floppy with:
dd if=/dev/fd0 of=/tmp/floppyimage
Also extract F<kernel.sys> from the floppy. You can do this from the
image using the mtools package, by specifying a file as a I<drive>
with a declaration like this in F<~/.mtoolsrc>:
drive x: file="/tmp/floppyimage"
Then run:
mcopy x:kernel.sys .
Then run mknbi by:
mknbi-fdos kernel.sys /tmp/floppyimage > freedos.nb
where F<kernel.sys> and F</tmp/floppyimage> are the files extracted above.
Then move F<freedos.nb> to where the network booting process expects to
find it.
If you have got it to netboot successfully, then you can go back and
add your files to the floppy image. You can delete F<kernel.sys> in
the floppy image to save space, that is not needed. Note that you can
create a floppy image of any size you desire with the mformat program
from mtools, you are not restricted to the actual size of the boot floppy.
=head1 MKNBI-FDOS OPTIONS
B<--harddisk> Make the boot ramdisk the first hard disk, i.e. C:. One
reason you might want to do this is because you want to use the real
floppy. The limit on "disk size" in the boot image is not raised by this
option so that is not a reason to use this option. This option is
incompatible with --disableharddisk.
B<--disableharddisk> When the ramdisk is simulating a floppy disk drive,
this switch will disable hard disk accesses. This is necessary if the
client should use a network file system as drive C:, which is only
possible if there are no hard disks found by DOS. This option is
incompatible with --harddisk.
B<--nosquash> Do not try to chop unused sectors from the end of the
floppy image. This increases the boot image size and hence loading
time if the FAT filesystem on the floppy is mostly empty but you may
wish to use this option if you have doubts as to whether the squashing
algorithm is working correctly.
B<--rdbase=>I<0xNNNNNNNN> Set the ramdisk load address. The default
load address for the ramdisk is 0x110000. It can be moved higher
(lower will not work) if for some reason you need to load other stuff
at the address it currently occupies. As this is a linear address and
not a segment address, the last 4 bits are not used and should be 0.
=head1 MKNBI-DOS
B<mknbi-dos> makes a boot image from a floppy image containing a
bootable DOS filesystem. It is not necessary to build the filesystem on
a physical floppy if you have the mtools package, but you need a
bootable floppy of any size to start with. First extract the boot block
from the floppy, this boot block must match the DOS kernel files you
will copy in the next step:
dd if=/dev/fd0 of=bootblock bs=512 count=1
Then get the DOS kernel files (this is correct for DR-DOS, the names
are different in MS-DOS, IO.SYS and MSDOS.SYS):
mcopy a:IBMBIO.COM a:IBMDOS.COM a:COMMAND.COM .
Next make an entry in F<~/.mtoolsrc> to declare a floppy to be mapped
to a file:
drive x: file="/tmp/floppyimage"
Now format a floppy of the desired size, in this example a 2.88 MB floppy,
at the same time writing the bootblock onto it:
mformat -C -t 80 -s 36 -h 2 -B bootblock x:
The size of the "floppy" is only limited by the limits on the number of
cylinders, sectors and heads, which are 1023, 63 and 255 respectively,
and the amount of RAM you are willing to allocate to the "floppy" in
memory. As RAM is precious, choose a size slightly bigger than what is
needed to hold your "floppy" files.
Finally, copy all your desired files onto the floppy:
mcopy IBMBIO.COM x:
mcopy IBMDOS.COM x:
mcopy COMMAND.COM x:
mcopy CONFIG.SYS AUTOEXEC.BAT APP.EXE APP.DAT ... x:
For MS-DOS substitute IO.SYS for IBMIO.COM, and MSDOS.SYS for
IBMDOS.COM. The case of the files must be preserved, it may not work if
VFAT lower case names are generated in the floppy image. Pay attention
to the order of copying as the boot block may expect the first two
entries on a newly formatted disk to be IO.SYS, MSDOS.SYS. Possibly too
COMMAND.COM has to be the third entry so we play safe. Thanks to Phil
Davey and Phillip Roa for these tips.
I have reports that the bootblock of MS-DOS 6.22 sometimes fails to boot
the ramdisk. You could try using the boot block from Netboot instead of
getting the boot block off the floppy. I have provided this boot block
in the distribution as altboot.bin, and in source form as altboot.S and
boot.inc. One essential thing is to make IO.SYS the first file on the
disk, or this bootblock will not work.
If you happen to have a media of the same size you could test if the
image is bootable by copying it onto the media, and then booting it:
dd if=/tmp/floppyimage of=/dev/fd0
Then run mknbi-dos over the image F</tmp/floppyimage> to create a
boot image:
mknbi-dos /tmp/floppyimage > dos.nb
Move F<dos.nb> to where the network booting process expects to find it.
=head1 MKNBI-DOS OPTIONS
B<--harddisk> Make the boot ramdisk the first hard disk, i.e. C:. One
reason you might want to do this is because you want to use the real
floppy. The limit on "disk size" in the boot image is not raised by this
option so that is not a reason to use this option. This option is
incompatible with --disableharddisk.
B<--disableharddisk> When the ramdisk is simulating a floppy disk drive,
this switch will disable hard disk accesses. This is necessary if the
client should use a network file system as drive C:, which is only
possible if there are no hard disks found by DOS. This option is
incompatible with --harddisk.
B<--nosquash> Do not try to chop unused sectors from the end of the
floppy image. This increases the boot image size and hence loading
time if the FAT filesystem on the floppy is mostly empty but you may
wish to use this option if you have doubts as to whether the squashing
algorithm is working correctly.
B<--rdbase=>I<0xNNNNNNNN> Set the ramdisk load address. The default
load address for the ramdisk is 0x110000. It can be moved higher
(lower will not work) if for some reason you need to load other stuff
at the address it currently occupies. As this is a linear address and
not a segment address, the last 4 bits are not used and should be 0.
=head1 BUGS
Please report all bugs to Etherboot users mailing list:
<https://sourceforge.net/mail/?group_id=4233>
=head1 SEE ALSO
Etherboot tutorial at C<http://etherboot.sourceforge.net/> Mtools package
is at C<http://wauug.erols.com/pub/knaff/mtools/> Make sure you have a
recent version, the ability to map a drive to a file is not present in
old versions.
=head1 COPYRIGHT
B<mknbi> is under the GNU Public License
=head1 AUTHOR
Ken Yap
mk{elf,nbi}-nfl was contributed by Robb Main of Genedyne.
=head1 DATE
See man page footer for date and version. Sorry, not available in the
HTML version.

View file

@ -1,60 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
*/
#include "2bload.h"
void * memcpy(void *dest, const void *src, size_t size) {
#if 0
BYTE * pb=(BYTE *)src, *pbd=(BYTE *)dest;
while(size--) *pbd++=*pb++;
#else
__asm__ __volatile__ (
" push %%esi \n"
" push %%edi \n"
" push %%ecx \n"
" cld \n"
" mov %0, %%esi \n"
" mov %1, %%edi \n"
" mov %2, %%ecx \n"
" push %%ecx \n"
" shr $2, %%ecx \n"
" rep movsl \n"
" pop %%ecx \n"
" and $3, %%ecx \n"
" rep movsb \n"
: :"S" (src), "D" (dest), "c" (size)
);
__asm__ __volatile__ (
" pop %ecx \n"
" pop %edi \n"
" pop %esi \n"
);
#endif
}
void * memset(void *dest, int data, size_t size)
{
char *p = dest;
while (size -- > 0)
{
*p ++ = data;
}
}
int _memcmp(const BYTE *pb, const BYTE *pb1, int n) {
while(n--) { if(*pb++ != *pb1++) return 1; }
return 0;
}

View file

@ -1,214 +0,0 @@
/*
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
2003-04-27 hamtitampti
*/
#include "2bload.h"
#include "sha1.h"
extern int decompress_kernel(char*out, char *data, int len);
DWORD PciWriteDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int dw)
{
DWORD base_addr = 0x80000000;
base_addr |= ((bus & 0xFF) << 16); // bus #
base_addr |= ((dev & 0x1F) << 11); // device #
base_addr |= ((func & 0x07) << 8); // func #
base_addr |= ((reg_off & 0xff));
IoOutputDword(0xcf8, base_addr );
IoOutputDword(0xcfc ,dw);
return 0;
}
DWORD PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off)
{
DWORD base_addr = 0x80000000;
base_addr |= ((bus & 0xFF) << 16); // bus #
base_addr |= ((dev & 0x1F) << 11); // device #
base_addr |= ((func & 0x07) << 8); // func #
base_addr |= ((func & 0x07) << 8);
base_addr |= ((reg_off & 0xff));
IoOutputDword(0xcf8, base_addr);
return IoInputDword(0xcfc);
}
void BootAGPBUSInitialization(void)
{
DWORD temp;
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x54, PciReadDword(BUS_0, DEV_1, FUNC_0, 0x54) | 0x88000000 );
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x64, (PciReadDword(BUS_0, DEV_0, FUNC_0, 0x64))| 0x88000000 );
temp = PciReadDword(BUS_0, DEV_0, FUNC_0, 0x6C);
IoOutputDword(0xcfc , temp & 0xFFFFFFFE);
IoOutputDword(0xcfc , temp );
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100);
}
/* ------------------------- Main Entry for after the ASM sequences ------------------------ */
extern void BootStartBiosLoader ( void ) {
// do not change this, this is linked to many many scipts
unsigned int PROGRAMM_Memory_2bl = 0x00100000;
unsigned int CROMWELL_Memory_pos = 0x03A00000;
unsigned int CROMWELL_compress_temploc = 0x02000000;
unsigned int Buildinflash_Flash[4] = { 0xfff00000,0xfff40000,0xfff80000,0xfffc0000};
unsigned int cromwellidentify = 1;
unsigned int flashbank = 3; // Default Bank
unsigned int cromloadtry = 0;
struct SHA1Context context;
unsigned char SHA1_result[20];
unsigned char bootloaderChecksum[20];
unsigned int bootloadersize;
unsigned int loadretry;
unsigned int compressed_image_start;
unsigned int compressed_image_size;
unsigned int Biossize_type;
int temp;
int validimage;
memcpy(&bootloaderChecksum[0],(void*)PROGRAMM_Memory_2bl,20);
memcpy(&bootloadersize,(void*)(PROGRAMM_Memory_2bl+20),4);
memcpy(&compressed_image_start,(void*)(PROGRAMM_Memory_2bl+24),4);
memcpy(&compressed_image_size,(void*)(PROGRAMM_Memory_2bl+28),4);
memcpy(&Biossize_type,(void*)(PROGRAMM_Memory_2bl+32),4);
SHA1Reset(&context);
SHA1Input(&context,(void*)(PROGRAMM_Memory_2bl+20),bootloadersize-20);
SHA1Result(&context,SHA1_result);
if (_memcmp(&bootloaderChecksum[0],&SHA1_result[0],20)==0) {
// HEHE, the Image we copy'd into ram is SHA-1 hash identical, this is Optimum
BootPerformPicChallengeResponseAction();
} else {
// Bad, the checksum does not match, but we can nothing do now, we wait until PIC kills us
while(1);
}
// Sets the Graphics Card to 60 MB start address
(*(unsigned int*)0xFD600800) = (0xf0000000 | ((64*0x100000) - 0x00400000));
BootAGPBUSInitialization();
(*(unsigned int*)(0xFD000000 + 0x100200)) = 0x03070103 ;
(*(unsigned int*)(0xFD000000 + 0x100204)) = 0x11448000 ;
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x84, 0x7FFFFFF); // 128 MB
// Lets go, we have finished, the Most important Startup, we have now a valid Micro-loder im Ram
// we are quite happy now
validimage=0;
flashbank=3;
for (loadretry=0;loadretry<100;loadretry++) {
cromloadtry=0;
if (Biossize_type==0) {
// Means we have a 256 kbyte image
flashbank=3;
}
else if (Biossize_type==1) {
// Means we have a 1MB image
// If 25 load attempts failed, we switch to the next bank
switch (loadretry) {
case 0:
flashbank=1;
break;
case 25:
flashbank=2;
break;
case 50:
flashbank=0;
break;
case 75:
flashbank=3;
break;
}
}
cromloadtry++;
// Copy From Flash To RAM
memcpy(&bootloaderChecksum[0],(void*)(Buildinflash_Flash[flashbank]+compressed_image_start),20);
memcpy((void*)CROMWELL_compress_temploc,(void*)(Buildinflash_Flash[flashbank]+compressed_image_start+20),compressed_image_size);
memset((void*)(CROMWELL_compress_temploc+compressed_image_size),0x00,20*1024);
// Lets Look, if we have got a Valid thing from Flash
SHA1Reset(&context);
SHA1Input(&context,(void*)(CROMWELL_compress_temploc),compressed_image_size);
SHA1Result(&context,SHA1_result);
if (_memcmp(&bootloaderChecksum[0],SHA1_result,20)==0) {
// The Checksum is good
// We start the Cromwell immediatly
I2cSetFrontpanelLed(I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3 );
BufferIN = (unsigned char*)(CROMWELL_compress_temploc);
BufferINlen=compressed_image_size;
BufferOUT = (unsigned char*)CROMWELL_Memory_pos;
decompress_kernel(BufferOUT, BufferIN, BufferINlen);
// This is a config bit in Cromwell, telling the Cromwell, that it is a Cromwell and not a Xromwell
flashbank++; // As counting starts with 0, we increase +1
memcpy((void*)(CROMWELL_Memory_pos+0x20),&cromwellidentify,4);
memcpy((void*)(CROMWELL_Memory_pos+0x24),&cromloadtry,4);
memcpy((void*)(CROMWELL_Memory_pos+0x28),&flashbank,4);
memcpy((void*)(CROMWELL_Memory_pos+0x2C),&Biossize_type,4);
validimage=1;
break;
}
}
if (validimage==1) {
I2cSetFrontpanelLed(
I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_GREEN2 | I2C_LED_GREEN3 |
I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3
);
// We now jump to the cromwell, Good bye 2bl loader
// This means: jmp CROMWELL_Memory_pos == 0x03A00000
__asm __volatile__ (
"wbinvd\n"
"cld\n"
"ljmp $0x10, $0x03A00000\n"
);
// We are not Longer here
}
// Bad, we did not get a valid im age to RAM, we stop and display a error
//I2cSetFrontpanelLed(I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3 );
I2cSetFrontpanelLed(
I2C_LED_GREEN0 | I2C_LED_GREEN1 | I2C_LED_GREEN2 | I2C_LED_GREEN3 |
I2C_LED_RED0 | I2C_LED_RED1 | I2C_LED_RED2 | I2C_LED_RED3
);
// I2CTransmitWord(0x10, 0x1901); // no reset on eject
// I2CTransmitWord(0x10, 0x0c00); // eject DVD tray
while(1);
}

View file

@ -1,653 +0,0 @@
/*
*
* BIOS ROM Startup Assembler
* (C)2002 Andy, Michael, Paul, Steve
* Original top and bottom ROM code by Steve from an idea by Michael
* -- NOTE: Comment removed, the top / bottom Code changed to turnaround code.
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/*
Rewritten from Original .bin linking to compiler system by Lehner Franz (franz@caos.at)
Rewritten to Dual Boot concept for 2BL loading
New written CPU Inits by Lehner Franz (franz@caos.at)
Written New Working Xcodes + Xcode compiler by Lehner Franz (franz@caos.at)
Focus support by Lehner Franz (franz@caos.at)
Xcalibur support by Lehner Franz (franz@caos.at)
*/
#include "2bconsts.h"
#define xcode_peek(val1) .byte 0x2; .long val1 ; .long 0x0 ;
#define xcode_poke(val1,val2) .byte 0x3; .long val1 ; .long val2 ;
#define xcode_pciout(val1,val2) .byte 0x4; .long val1 ; .long val2 ;
#define xcode_pciin_a(val1) .byte 0x5; .long val1 ; .long 0x0 ;
#define xcode_bittoggle(val1,val2) .byte 0x6; .long val1 ; .long val2 ;
#define xcode_ifgoto(val1,val2) .byte 0x8; .long val1 ; .long (9*(val2-1)) ;
#define xcode_outb(val1,val2) .byte 0x11; .long val1 ; .long val2 ;
#define xcode_inb(val1) .byte 0x12; .long val1 ; .long 0x0 ;
#define xcode_poke_a(val1) .byte 0x7; .long 0x3; .long val1 ;
#define xcode_pciout_a(val1) .byte 0x7; .long 0x4; .long val1 ;
#define xcode_outb_a(val1) .byte 0x7; .long 0x11; .long val1 ;
#define xcode_goto(val1) .byte 0x9; .long 0x0; .long (9*(val1-1));
#define xcode_END(val1) .byte 0xEE; .long val1 ; .long 0x0;
#define SMBUS 0x0000c000
#define SMB_xcode_Write(val1,val2); xcode_outb(SMBUS+8, val1); \
xcode_outb(SMBUS+6, val2); \
xcode_outb(SMBUS+2, 0x0000000a); \
xcode_inb(SMBUS); \
xcode_ifgoto(0x00000010,-1); \
xcode_outb(SMBUS, 0x00000010);
.code32
.section .low_rom, "ax"
.org 0x0
/* MCPX Magic Values */
.long 0xff000009
.long 0xff000008
.long 0x2b16d065
.long 0x3346322d
.long 0x01010101
.long 0x08080808
.long 0x00000801
#ifndef MCPXREVD5
.long 0xc8fc7c8a // MCPX =< D5
.long 0x44290213
.long 0x90004998
.long 0x0
#else
.long 0xc8b4588a // MCPX 1.6 > D5
.long 0x00100000
.long 0x00050aa7
.long 0xf0000000
#endif
.long 0xffffffff
.long 0xffffffff
.org 0x40
.long _start_checksum // This number will be overwritten
// With imagebld, but we need a temp value
.org 0x6c
.long 0x00000107
.org 0x70 // MCPX Config Area
.long 0x0000000f
.long 0x40004400
#ifndef MCPXREVD5
.long 0x12d10070
#else
.long 0x16ce0090
#endif
.long 0x00000c90
// Here, the Bytecode interpretor starts
.org 0x80
xcode_pciout(0x80000884, 0x00008001);
xcode_pciout(0x80000810, 0x00008001);
xcode_pciout(0x80000804, 0x00000003);
xcode_outb(0x00008049, 0x00000008);
xcode_outb(0x000080d9, 0x00000000);
xcode_outb(0x00008026, 0x00000001);
xcode_pciout(0x8000f04c, 0x00000001);
xcode_pciout(0x8000f018, 0x00010100);
xcode_pciout(0x80000084, 0x07ffffff);
xcode_pciout(0x8000f020, 0x0ff00f00);
xcode_pciout(0x8000f024, 0xf7f0f000);
xcode_pciout(0x80010010, 0x0f000000);
xcode_pciout(0x80010014, 0xf0000000);
xcode_pciout(0x80010004, 0x00000007);
xcode_pciout(0x8000f004, 0x00000007);
xcode_poke(0x0f0010b0, 0x07633461);
xcode_poke(0x0f0010cc, 0x66660000);
xcode_peek(0x0f101000);
xcode_bittoggle(0x000c0000,0x00000000);
xcode_ifgoto(0x00000000,6);
xcode_peek(0x0f101000);
xcode_bittoggle(0xe1f3ffff,0x80000000);
xcode_poke_a(0x0f101000);
xcode_poke(0x0f0010b8, 0xeeee0000);
xcode_goto(11);
xcode_ifgoto(0x000c0000,6);
xcode_peek(0x0f101000);
xcode_bittoggle(0xe1f3ffff,0x860c0000);
xcode_poke_a(0x0f101000);
xcode_poke(0x0f0010b8, 0xffff0000);
xcode_goto(5);
xcode_peek(0x0f101000);
xcode_bittoggle(0xe1f3ffff,0x820c0000);
xcode_poke_a(0x0f101000);
xcode_poke(0x0f0010b8, 0x11110000);
xcode_poke(0x0f0010d4, 0x00000009);
xcode_poke(0x0f0010b4, 0x00000000);
xcode_poke(0x0f0010bc, 0x00005866);
xcode_poke(0x0f0010c4, 0x0351c858);
xcode_poke(0x0f0010c8, 0x30007d67);
xcode_poke(0x0f0010d8, 0x00000000);
xcode_poke(0x0f0010dc, 0xa0423635);
xcode_poke(0x0f0010e8, 0x0c6558c6);
xcode_poke(0x0f100200, 0x03070103);
xcode_poke(0x0f100410, 0x11000016);
xcode_poke(0x0f100330, 0x84848888);
xcode_poke(0x0f10032c, 0xffffcfff);
xcode_poke(0x0f100328, 0x00000001);
xcode_poke(0x0f100338, 0x000000df);
// Set up the SM - bus controller
xcode_pciout(0x80000904, 0x00000001);
xcode_pciout(0x80000914, 0x0000c001);
xcode_pciout(0x80000918, 0x0000c201);
xcode_outb(0x0000c200, 0x00000070);
/* ---------- focus Starts here ------------------------- */
xcode_outb(0x0000c004, 0x000000d4);
//I2CTransmitWord(0x6a,0x0c00);
xcode_outb(SMBUS+8, 0x0000000c);
xcode_outb(SMBUS+6, 0x00000000);
xcode_outb(SMBUS+2, 0x0000000a);
xcode_inb(SMBUS);
xcode_ifgoto(0x00000010,2)
xcode_goto(5); // I2C write Succeed, we make the Next Focus write
xcode_bittoggle(0x00000008,0x00000000);
xcode_ifgoto(0x00000000,-4)
xcode_outb(SMBUS, 0x000000ff);
xcode_goto(9); // I2C Write Failed, we go to conexant
xcode_outb(SMBUS, 0x00000010);
//I2CTransmitWord(0x6a,0x0d20);
SMB_xcode_Write(0x0d,0x20); // +6
// Focus Code finished, we jump over the conexant / crystal code
xcode_goto(64); // Jump to end of Connexant inits
/* ---------- focus Over ------------------------- */
/* ---------- Conexant Starts here ------------------------- */
// Last Cycle ok
xcode_outb(SMBUS, 0x00000010);
// Connexant Slave Address
xcode_outb(0x0000c004, 0x0000008a);
//I2CTransmitWord(0x45,0xba3f);
xcode_outb(SMBUS+8, 0x000000ba);
xcode_outb(SMBUS+6, 0x0000003f);
xcode_outb(SMBUS+2, 0x0000000a);
xcode_inb(SMBUS);
xcode_ifgoto(0x00000010,2)
xcode_goto(19); // I2C write Succeed, we continue with conexant
xcode_bittoggle(0x00000008,0x00000000);
xcode_ifgoto(0x00000000,-4)
xcode_outb(SMBUS, 0x000000ff);
xcode_outb(SMBUS, 0x00000010); // I2C Write Failed, I think we have a Xcalibur box
// Xcalibur Slave Address
xcode_outb(0x0000c004, 0x000000E0);
//I2CTransmitWord(0x70,0x00);
SMB_xcode_Write(0x0,0x0); // +6
//I2CTransmitWord(0x70,0x00);
SMB_xcode_Write(0xb8,0x00); // +6
xcode_goto(38); // jump to conexant end
// Xcalibur over, now Conexant again
xcode_outb(SMBUS, 0x00000010);
//I2CTransmitWord(0x45,0x6c46);
SMB_xcode_Write(0x6c,0x46); // +6
//I2CTransmitWord(0x45,0xb800);
SMB_xcode_Write(0xb8,0x00); // +6
//I2CTransmitWord(0x45,0xce19);
SMB_xcode_Write(0xce,0x19); // +6
//I2CTransmitWord(0x45,0xc69c);
SMB_xcode_Write(0xc6,0x9c); // +6
//I2CTransmitWord(0x45,0x3208);
SMB_xcode_Write(0x32,0x08); // +6
//I2CTransmitWord(0x45,0xc401);
SMB_xcode_Write(0xc4,0x01); // +6
/* ---------- Conexant Over ------------------------- */
// PIC SLAVE Address (Write)
xcode_outb(SMBUS+4, 0x00000020);
// I2Ctransmit(0x20,0x1,0x0);
SMB_xcode_Write(0x01,0x00); // +6
// PIC SLAVE Address (Read)
xcode_outb(SMBUS+4, 0x00000021);
// I2Cgetbyte(0x8a,0x1);
xcode_outb(SMBUS+8, 0x00000001);
xcode_outb(SMBUS+2, 0x0000000a);
xcode_inb(SMBUS);
xcode_ifgoto(0x00000010,-1)
xcode_outb(SMBUS, 0x00000010);
// If SMC version does not match ... ?????
xcode_inb(SMBUS+6);
#if 0
xcode_ifgoto(0x00000050,2);
xcode_goto(2);
xcode_pciout(0x8000036c, 0x01000000);
#endif
xcode_poke(0x0f680500, 0x00011c01);
xcode_poke(0x0f68050c, 0x000a0400);
xcode_poke(0x0f001220, 0x00000000);
xcode_poke(0x0f001228, 0x00000000);
xcode_poke(0x0f001264, 0x00000000);
xcode_poke(0x0f001210, 0x00000010);
xcode_peek(0x0f101000);
xcode_bittoggle(0x06000000,0x00000000);
xcode_ifgoto(0x00000000,4);
xcode_poke(0x0f001214, 0x48480848);
xcode_poke(0x0f00122c, 0x88888888);
xcode_goto(7);
xcode_ifgoto(0x06000000,4);
xcode_poke(0x0f001214, 0x09090909);
xcode_poke(0x0f00122c, 0xaaaaaaaa);
xcode_goto(3);
xcode_poke(0x0f001214, 0x09090909);
xcode_poke(0x0f00122c, 0xaaaaaaaa);
xcode_poke(0x0f001230, 0xffffffff);
xcode_poke(0x0f001234, 0xaaaaaaaa);
xcode_poke(0x0f001238, 0xaaaaaaaa);
xcode_poke(0x0f00123c, 0x8b8b8b8b);
xcode_poke(0x0f001240, 0xffffffff);
xcode_poke(0x0f001244, 0x8b8b8b8b);
xcode_poke(0x0f001248, 0x8b8b8b8b);
xcode_poke(0x0f1002d4, 0x00000001);
xcode_poke(0x0f1002c4, 0x00100042);
xcode_poke(0x0f1002cc, 0x00100042);
xcode_poke(0x0f1002c0, 0x00000011);
xcode_poke(0x0f1002c8, 0x00000011);
xcode_poke(0x0f1002c0, 0x00000032);
xcode_poke(0x0f1002c8, 0x00000032);
xcode_poke(0x0f1002c0, 0x00000132);
xcode_poke(0x0f1002c8, 0x00000132);
xcode_poke(0x0f1002d0, 0x00000001);
xcode_poke(0x0f1002d0, 0x00000001);
xcode_poke(0x0f100210, 0x80000000);
xcode_poke(0x0f00124c, 0xaa8baa8b);
xcode_poke(0x0f001250, 0x0000aa8b);
xcode_poke(0x0f100228, 0x081205ff);
xcode_poke(0x0f001218, 0x00010000);
xcode_pciin_a(0x80000860);
xcode_bittoggle(0xffffffff,0x00000400);
xcode_pciout_a(0x80000860);
xcode_pciout(0x8000084c, 0x0000fdde);
xcode_pciout(0x8000089c, 0x871cc707);
xcode_pciin_a(0x800008b4);
xcode_bittoggle(0xfffff0ff,0x00000f00);
xcode_pciout_a(0x800008b4);
xcode_pciout(0x80000340, 0xf0f0c0c0);
xcode_pciout(0x80000344, 0x00c00000);
xcode_pciout(0x8000035c, 0x04070000);
xcode_pciout(0x8000036c, 0x00230801);
xcode_pciout(0x8000036c, 0x01230801);
xcode_goto(1);
xcode_goto(1);
xcode_poke(0x0f100200, 0x03070103);
xcode_poke(0x0f100204, 0x11448000);
xcode_pciout(0x8000103c, 0x00000000);
xcode_outb(SMBUS, 0x00000010);
/* ---- Report Memory Size to PIC scratch register ---- */
// We emulate Good memory result to PIC
//xcode_pciin_a(0x8000183c);
//xcode_bittoggle(0x000000ff,0x00000000);
//xcode_outb_a(SMBUS+6);
xcode_outb(SMBUS+4, 0x00000020);
SMB_xcode_Write(0x13,0x0f); // +6
SMB_xcode_Write(0x12,0xf0); // +6
/* ---- Reload Nvidia Registers ------------------------*/
xcode_pciout(0x8000f020, 0xfdf0fd00);
xcode_pciout(0x80010010, 0xfd000000);
// overflow trick
xcode_poke(0x00000000, 0xfc1000ea);
xcode_poke(0x00000004, 0x000008ff);
xcode_END(0x806);
// Note: never change this from offset 0x1000 ....
// This is the Main Entry point ....
.org 0x1000
// Good Morning CPU
// NOTE:
/*
We come here form the high rom section Jump
*/
// Clear Intel Interrupts in Processor Register
// Everytime very good, specially when comming out of a running envoronment
movl $0x1b, %ecx
xor %eax, %eax
xor %edx, %edx
wrmsr
// Interrupts now Dead
xor %eax, %eax
xor %edx, %edx
xor %ecx, %ecx
// kill the cache = Disable bit 30 + 29 = CD + NW
// CD = Cache Disable (disable = 1)
// NW Not write through (disable = 1)
mov %cr0, %eax
orl $0x60000000, %eax
mov %eax, %cr0
wbinvd
// We clear the cr3 register
mov %eax, %eax
mov %eax, %cr3
// Clear Mmeory Type register
movl $0x2ff, %ecx
xor %eax, %eax
xor %edx, %edx
wrmsr
/*
We are setting the Ram Init's now to set up the Regions in the Ram
*/
// MTRR for RAM
// from address 0, Writeback Caching, 128MB range
movl $0x200, %ecx
movl $0x00000000, %edx
movl $0x00000006, %eax // == WB_CACHE == 6
//movl $0x00000004, %eax // Temporary, as USB development
wrmsr
// MASK0 set to 0xf8000[000] == 128M
movl $0x201, %ecx
movl $0x0000000f, %edx
movl $0xf8000800, %eax
wrmsr
// MTRR for shadow RAM
// from address 0xf0000000, Write-combining Caching, 128MB range
movl $0x202, %ecx
movl $0x00000000, %edx
movl $0xf0000001, %eax // Write-Combining == 1
wrmsr
// MASK0 set to 0xf8000[000] == 128M
movl $0x203, %ecx
movl $0x0000000f, %edx
movl $0xf8000800, %eax
wrmsr
// MTRR for FLASH
movl $0x204, %ecx
movl $0x00000000, %edx
movl $0xFff00000, %eax // We set to Uncacheable
wrmsr
movl $0x205, %ecx
movl $0x0000000f, %edx
movl $0xfff00800, %eax
wrmsr
xor %eax, %eax
xor %edx, %edx
movl $0x206, %ecx // IA32_MTRR_PHYS Base 3
wrmsr
movl $0x207, %ecx // IA32_MTRR_PHYS_MASK 3
wrmsr
movl $0x208, %ecx // IA32_MTRR_PHYS Base 4
wrmsr
movl $0x209, %ecx // IA32_MTRR_PHYS_MASK 4
wrmsr
movl $0x20a, %ecx // IA32_MTRR_PHYS Base 5
wrmsr
movl $0x20b, %ecx // IA32_MTRR_PHYS_MASK 5
wrmsr
movl $0x20c, %ecx // IA32_MTRR_PHYS Base 6
wrmsr
movl $0x20d, %ecx // IA32_MTRR_PHYS_MASK 6
wrmsr
movl $0x20e, %ecx // IA32_MTRR_PHYS Base 7
wrmsr
movl $0x20f, %ecx // IA32_MTRR_PHYS_MASK 7
wrmsr
// Define Memory in IA32_MTRR_DEF_TYPE
movl $0x2ff, %ecx
xor %edx, %edx
movl $0x800, %eax //Enable MTRRs
wrmsr
/* turn on normal cache */
// bit 30 + 29 = CD + NW
// CD = Cache Disable (disable = 1)
// NW Not write through (disable = 1)
movl %cr0, %eax
mov %eax, %ebx
andl $0x9FFFFFFF,%eax
movl %eax, %cr0
cld
// copy everything into RAM
mov $_ram_location, %edi
mov $_start_ramcopy, %esi
mov $(_size_ramcopy + 100), %ecx
shr $2,%ecx // We dividy / 4, as we copy Dword oriented
rep movsl
jmp initaftermemcpy
/*
We leave Flash at this point, we never come back to it anymore.
the following ASM instructions below, already are linked to memory (look to the ldscript in this case)
*/
.section .text, "ax"
// Note: We are in Memory here, not in Flash anylonger,
// we have been copy'd here and linked for memory, as we reside in section .text
// Look to LDscript
.global MemoryChecksum
MemoryChecksum:
// The SHA-1 Hashsum is dumped here after with ImageBLD
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00
.long _size_sha1hash
.long 0x00 // Will be dumped in by imagebld ->compressed_image_start;
.long 0x00 // Will be dumped in by imagebld ->compressed_image_size;
.long 0x00 // Will be dumped in by imagebld ->0 .. 256kb image, 1 .. 1MB image
.org 0x40 // We have linkbase for this programm = 0x100000 + 0x40 = divisable /4 .. so CPU likes it
tableGdt:
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0x00 dummy
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0xcf, 0x00 // 0x08 code32
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0xcf, 0x00 // 0x10 code32
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0xcf, 0x00 // 0x18 data32
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9b, 0x8f, 0x00 // 0x20 code16 (8f indicates 4K granularity, ie, huge limit)
.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x93, 0x8f, 0x00 // 0x28 data16
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Dummy
tableGdtDescriptor:
.word 0x30
.long tableGdt
.word 0x0 // fill Word, so we get alliged again
tableIdtDescriptor:
.word 2048
.long 0x400000
.word 0x0 // fill Word, so we get alliged again
initaftermemcpy:
/*
These Init Codes Can be found in the 2'nd Bootloader
*/
// We set up a GDT now, this is not necessary needed,
// but i perfeer a GDT, as we have more ability with commands
// We clear the IDT in RAM
xor %eax,%eax
mov $0x5000,%ecx
mov $0x400000,%edi
rep stosb
lidt tableIdtDescriptor
lgdt tableGdtDescriptor
// set up selectors for everything
xor %eax, %eax
lldt %ax
// Reload CS as 0010 from the new GDT using a far jump
.byte 0xEA // jmp far 0010:reload_cs
.long reload_cs
.word 0x0010
.align 16
reload_cs:
// CS is now a valid entry in the GDT. Set SS, DS, and ES to valid
// descriptors, but clear FS and GS as they are not necessary.
// Set SS, DS, and ES to a data32 segment with maximum limit.
movw $0x0018, %ax
mov %eax, %ss
mov %eax, %ds
mov %eax, %es
// Clear FS and GS
xor %eax, %eax
mov %eax, %fs
mov %eax, %gs
movl $ 0x1ffff0,%esp
mov $0x8, %al
mov $0x61, %dx
out %al, %dx
// Enable IDE and NIC
mov $0x8000088C, %eax
movw $0xcf8, %dx
outl %eax, %dx
movw $0xcfc, %dx
movl $0x40000000, %eax
outl %eax, %dx
// CPU Whoami ? sesless ?
mov $0x80000080, %eax
movw $0xcf8, %dx
outl %eax, %dx
movw $0xcfc, %dx
movl $0x100, %eax
outl %eax, %dx
// this can be found in BootResetAction.c
jmp BootStartBiosLoader

View file

@ -1,153 +0,0 @@
/*
* I2C-related code
* AG 2002-07-27
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "2bload.h"
// ---------------------------- I2C -----------------------------------------------------------
//
// get a value from a given device address
// errors will have b31 set, ie, will be negative, otherwise fetched byte in LSB of return
int I2CTransmitByteGetReturn(BYTE bPicAddressI2cFormat, BYTE bDataToWrite)
{
int nRetriesToLive=400;
//if(IoInputWord(I2C_IO_BASE+0)&0x8000) { }
while(IoInputWord(I2C_IO_BASE+0)&0x0800) ; // Franz's spin while bus busy with any master traffic
while(nRetriesToLive--) {
IoOutputByte(I2C_IO_BASE+4, (bPicAddressI2cFormat<<1)|1);
IoOutputByte(I2C_IO_BASE+8, bDataToWrite);
IoOutputWord(I2C_IO_BASE+0, 0xffff); // clear down all preexisting errors
IoOutputByte(I2C_IO_BASE+2, 0x0a);
{
BYTE b=0x0;
while( (b&0x36)==0 ) { b=IoInputByte(I2C_IO_BASE+0); }
if(b&0x24) {
//bprintf("I2CTransmitByteGetReturn error %x\n", b);
}
if(!(b&0x10)) {
//bprintf("I2CTransmitByteGetReturn no complete, retry\n");
} else {
return (int)IoInputByte(I2C_IO_BASE+6);
}
}
}
return ERR_I2C_ERROR_BUS;
}
// transmit a word, no returned data from I2C device
int I2CTransmitWord(BYTE bPicAddressI2cFormat, WORD wDataToWrite)
{
int nRetriesToLive=400;
while(IoInputWord(I2C_IO_BASE+0)&0x0800) ; // Franz's spin while bus busy with any master traffic
while(nRetriesToLive--) {
IoOutputByte(I2C_IO_BASE+4, (bPicAddressI2cFormat<<1)|0);
IoOutputByte(I2C_IO_BASE+8, (BYTE)(wDataToWrite>>8));
IoOutputByte(I2C_IO_BASE+6, (BYTE)wDataToWrite);
IoOutputWord(I2C_IO_BASE+0, 0xffff); // clear down all preexisting errors
IoOutputByte(I2C_IO_BASE+2, 0x1a);
{
BYTE b=0x0;
while( (b&0x36)==0 ) { b=IoInputByte(I2C_IO_BASE+0); }
if(b&0x24) {
//bprintf("I2CTransmitWord error %x\n", b);
}
if(!(b&0x10)) {
//bprintf("I2CTransmitWord no complete, retry\n");
} else {
return ERR_SUCCESS;
}
}
}
return ERR_I2C_ERROR_BUS;
}
// ---------------------------- PIC challenge/response -----------------------------------------------------------
//
// given four bytes, returns a WORD
// LSB of return is the 'first' byte, MSB is the 'second' response byte
WORD BootPicManipulation(
BYTE bC,
BYTE bD,
BYTE bE,
BYTE bF
) {
int n=4;
BYTE
b1 = 0x33,
b2 = 0xed,
b3 = ((bC<<2) ^ (bD +0x39) ^ (bE >>2) ^ (bF +0x63)),
b4 = ((bC+0x0b) ^ (bD>>2) ^ (bE +0x1b))
;
while(n--) {
b1 += b2 ^ b3;
b2 += b1 ^ b4;
}
return (WORD) ((((WORD)b2)<<8) | b1);
}
// actual business of getting I2C data from PIC and reissuing munged version
// returns zero if all okay, else error code
int BootPerformPicChallengeResponseAction()
{
BYTE bC, bD, bE, bF;
int n;
n=I2CTransmitByteGetReturn( 0x10, 0x1c );
if(n<0) return n;
bC=n;
n=I2CTransmitByteGetReturn( 0x10, 0x1d );
if(n<0) return n;
bD=n;
n=I2CTransmitByteGetReturn( 0x10, 0x1e );
if(n<0) return n;
bE=n;
n=I2CTransmitByteGetReturn( 0x10, 0x1f );
if(n<0) return n;
bF=n;
{
WORD w=BootPicManipulation(bC, bD, bE, bF);
I2CTransmitWord( 0x10, 0x2000 | (w&0xff));
I2CTransmitWord( 0x10, 0x2100 | (w>>8) );
}
// continues as part of video setup....
return ERR_SUCCESS;
}
extern int I2cSetFrontpanelLed(BYTE b)
{
I2CTransmitWord( 0x10, 0x800 | b); // sequencing thanks to Jarin the Penguin!
I2CTransmitWord( 0x10, 0x701);
return ERR_SUCCESS;
}

View file

@ -1,71 +0,0 @@
/*
*
* includes for startup code in a form usable by the .S files
*
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#define PCI_CFG_ADDR 0x0CF8
#define PCI_CFG_DATA 0x0CFC
#define MTRR_DEF 0x2ff
#define MTRR_DEF_TYPE 0x800
#define MTRR_PHYSBASE 0x200
#define MTRR_LAST 0x20F
#define WB_CACHE 6
#define BASE0_H 0
#define BASE0_L WB_CACHE
#define MASK0_H 0x0F
#define MASK0_L 0xFC000800
#define BASE1_H 0
#define BASE1_L 0xFFF80005
#define MASK1_H 0x0F
#define MASK1_L 0x0FFF80800
#define I2C_IO_BASE 0xc000
#define BUS_0 0
#define BUS_1 1
#define DEV_0 0
#define DEV_1 1
#define DEV_2 2
#define DEV_3 3
#define DEV_4 4
#define DEV_5 5
#define DEV_6 6
#define DEV_7 7
#define DEV_8 8
#define DEV_9 9
#define DEV_a 0xa
#define DEV_b 0xb
#define DEV_c 0xc
#define DEV_d 0xd
#define DEV_e 0xe
#define DEV_f 0xf
#define DEV_10 0x10
#define DEV_11 0x11
#define DEV_12 0x12
#define DEV_13 0x13
#define DEV_14 0x14
#define DEV_15 0x15
#define DEV_16 0x16
#define DEV_17 0x17
#define DEV_18 0x18
#define DEV_19 0x19
#define DEV_1a 0x1a
#define DEV_1b 0x1b
#define DEV_1c 0x1c
#define DEV_1d 0x1d
#define DEV_1e 0x1e
#define DEV_1f 0x1f
#define FUNC_0 0

View file

@ -1,101 +0,0 @@
/***************************************************************************
Includes used by XBox boot code
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "2bconsts.h"
#include "stdint.h"
#include "cromwell_types.h"
/////////////////////////////////
// LED-flashing codes
// or these together as argument to I2cSetFrontpanelLed
enum {
I2C_LED_RED0 = 0x80,
I2C_LED_RED1 = 0x40,
I2C_LED_RED2 = 0x20,
I2C_LED_RED3 = 0x10,
I2C_LED_GREEN0 = 0x08,
I2C_LED_GREEN1 = 0x04,
I2C_LED_GREEN2 = 0x02,
I2C_LED_GREEN3 = 0x01
};
///////////////////////////////
/* BIOS-wide error codes all have b31 set */
enum {
ERR_SUCCESS = 0, // completed without error
ERR_I2C_ERROR_TIMEOUT = 0x80000001, // I2C action failed because it did not complete in a reasonable time
ERR_I2C_ERROR_BUS = 0x80000002, // I2C action failed due to non retryable bus error
ERR_BOOT_PIC_ALG_BROKEN = 0x80000101 // PIC algorithm did not pass its self-test
};
//////// BootPerformPicChallengeResponseAction.c
/* ---------------------------- IO primitives -----------------------------------------------------------
*/
static __inline void IoOutputByte(WORD wAds, BYTE bValue) {
__asm__ __volatile__ ("outb %b0,%w1": :"a" (bValue), "Nd" (wAds));
}
static __inline void IoOutputWord(WORD wAds, WORD wValue) {
__asm__ __volatile__ ("outw %0,%w1": :"a" (wValue), "Nd" (wAds));
}
static __inline void IoOutputDword(WORD wAds, DWORD dwValue) {
__asm__ __volatile__ ("outl %0,%w1": :"a" (dwValue), "Nd" (wAds));
}
static __inline BYTE IoInputByte(WORD wAds) {
unsigned char _v;
__asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
static __inline WORD IoInputWord(WORD wAds) {
WORD _v;
__asm__ __volatile__ ("inw %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
static __inline DWORD IoInputDword(WORD wAds) {
DWORD _v;
__asm__ __volatile__ ("inl %w1,%0":"=a" (_v):"Nd" (wAds));
return _v;
}
// boot process
int BootPerformPicChallengeResponseAction(void);
// LED control (see associated enum above)
int I2cSetFrontpanelLed(BYTE b);
////////// BootResetActions.c
void BootStartBiosLoader(void);
///////// BootPerformPicChallengeResponseAction.c
int I2CTransmitWord(BYTE bPicAddressI2cFormat, WORD wDataToWrite);
int I2CTransmitByteGetReturn(BYTE bPicAddressI2cFormat, BYTE bDataToWrite);
void *memcpy(void *dest, const void *src, size_t size);
void *memset(void *dest, int data, size_t size);
int _memcmp(const BYTE *pb, const BYTE *pb1, int n);
unsigned char *BufferIN;
int BufferINlen;
unsigned char *BufferOUT;
int BufferOUTPos;

View file

@ -1,6 +0,0 @@
EXTRA_CFLAGS := -funroll-loops -I$(TOPDIR)/lib/crypt
O_TARGET := 2bBootStartup.o 2bBootStartBios.o 2bPicResponseAction.o \
2bBootLibrary.o 2bdecompress.o
include $(TOPDIR)/Rules.make

View file

@ -1,38 +0,0 @@
Memory Mapping 2BLoader for Cromwell Loading
0x0008 0000 Stack pointer TOP
0x0040 0000 IDT for the CPU
0x0010 0000 2BL programm for runnin in Memory
0x001F FFFF 2BL programm for runnin in Memory (ESP is there too)
0x0030 0000 Decompressor RAM
0x0100 0000 for 2bLoader Memory(0x1000000 size = 16 MB)
0x01FF FFFF End Memory
0x0200 0000 2bLoader Decompression Memory
0x024F FFFF 2bLoader Decompression MemoryEnd
0x0250 0000 2bLoader Dynamic Memory Start
0x03AF FFFF 2bLoader Dynamic Memory End
0x03A0 0000 c/x romwell Ramcopy Start (0x200000 size = 2MB)
0x03BF FFFF c/x romwell Ramcopy End
0x03C0 0000 Video Memory Start (4MB)
0x03FF FFFF Video Memory End
0x0400 0000 Physical Ram End
0xFFF0 0000 Flash Copy(0) Start
0xFFF3 FFFF Flash Copy(0) End
0xFFF4 0000 Flash Copy(1) Start
0xFFF7 FFFF Flash Copy(1) End
0xFFF8 0000 Flash Copy(2) Start
0xFFFB FFFF Flash Copy(2) End
0xFFFC 0000 Flash Copy(3) Start
0xFFFF FFFF Flash Copy(3) End
hamtitampti & ed

View file

@ -1,76 +0,0 @@
OUTPUT_FORMAT ("elf32-i386");
OUTPUT_ARCH(i386);
MEMORY
{
ram (rwx) : ORIGIN = 0, LENGTH = 64M
rom (rx) : ORIGIN = 0xFFFC0000, LENGTH = 256K
}
RAM_CODE = 0x00100000;
/* this should be changed depending the actual size of the rom */
ROM_SIZE = 256K;
LOW_ROM = 0xfffc0000;
TOP_ROM = ( LOW_ROM + ROM_SIZE - 512 );
TOP_ROM_LOAD = ( ROM_SIZE - 512 );
SECTIONS {
/* ROM Part of the programm */
.low_rom LOW_ROM : AT ( 0x0 ){
*(.low_rom);
_end_rom = . ;
}
/* RAM Part of the programm */
.text (RAM_CODE) : AT( SIZEOF(.low_rom) ) {
_ram_location = .;
_start_ramcopy = _end_rom;
*(.text);
_start_checksum = _start_ramcopy - LOW_ROM;
}
.data (RAM_CODE + SIZEOF(.text)) : AT( SIZEOF(.low_rom) + SIZEOF(.text)) {
*(.data);
*(.sdata);
*(.sdata2);
*(.got);
}
.rodata ( RAM_CODE + SIZEOF(.text) + SIZEOF(.data) ) : AT ( SIZEOF(.low_rom) + SIZEOF(.text) + SIZEOF(.data)) {
*(.rodata);
*(.rodata.str1.1);
*(.rodata.str1.32);
*(.rodata.cst4);
*(.rodata.cst8);
}
.bss ( RAM_CODE + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata) ) : AT ( SIZEOF(.low_rom) + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata)) {
_bss = .;
*(.bss)
*(.sbss)
*(COMMON)
_ebss = . ;
_heap = . ;
}
/* We need to copy the .data section to to upper memory */
_size_ramcopy = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata) + SIZEOF(.bss);
_size_sha1hash = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata);
/*
.high_rom TOP_ROM : AT (TOP_ROM_LOAD) {
_start_top_rom = . ;
. = . + ( 512 - sizeof_top );
*(.high_rom);
_end_top_rom = . ;
} = 0x90909090
*/
}

View file

@ -1,4 +0,0 @@
O_TARGET := vml_Startup.o
include $(TOPDIR)/Rules.make

View file

@ -1,3 +0,0 @@
kernel vmlboot
initrd vmlboot
rivafb y

View file

@ -1,25 +0,0 @@
.code32
.section .vmlinuz_start, "ax"
.org 0x00
.org 0x1f1
.byte 0x0A // *((BYTE *)0x901f1))+1)*512; .. Loader Takes us to 0x1600
.org 0x1600
xor %eax, %eax
xor %edx, %edx
cld
mov $0x03A00000, %edi // Destiation
mov $0x00100100, %esi // Source
mov $0x200000, %ecx // 2MB
rep movsb
wbinvd
cld
ljmp $0x10, $0x03A00000
.org 0x1700 // Here, we append the thing we want to load

View file

@ -1,58 +0,0 @@
/*
* loader script
*/
OUTPUT_FORMAT ("elf32-i386");
OUTPUT_ARCH(i386);
MEMORY
{
ram (rwx) : ORIGIN = 0, LENGTH = 64M
rom (rx) : ORIGIN = 0x03A00000, LENGTH = 2M
}
LOW_ROM = 0x00100000;
SECTIONS {
/* ROM allocations */
.vmlinuz_start LOW_ROM : AT ( 0 ){
*(.vmlinuz_start);
}
.rodata (LOW_ROM + SIZEOF(.vmlinuz_start)) : AT (SIZEOF(.vmlinuz_start)) {
*(.rodata);
*(.rodata.str1.1);
*(.rodata.str1.32);
*(.rodata.cst4);
*(.rodata.cst8);
}
/* ram allocations */
.data (LOW_ROM + SIZEOF(.vmlinuz_start) + SIZEOF(.rodata)) : AT( SIZEOF(.vmlinuz_start) + SIZEOF(.rodata) ) {
_start_data = .;
*(.data);
*(.sdata);
*(.sdata2);
*(.got);
_end_data = .;
}
/* the data (initialized globals) is moved to ram by the startup code */
.bss ( ADDR(.data) + SIZEOF(.data) ) : {
_bss = .;
*(.bss)
*(.sbss)
*(COMMON)
_ebss = . ;
_heap = . ;
}
}

View file

@ -1,8 +0,0 @@
O_TARGET := xbeboot.o
xbeboot.o:
%.o : %.S
${CC} -DASSEMBLER ${CFLAGS} -o $@ -c $<

View file

@ -1,259 +0,0 @@
// This 256 character 8x16 VGA font (IBM codepage 437) was taken from
// /usr/lib/kbd/consolefonts/default8x16.psf.gz in Linux Mandrake 8.2
font:
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD, 0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3, 0xE7, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7, 0xE7, 0xE7, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
.byte 0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x30, 0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x63, 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7, 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0xFE, 0x3E, 0x1E, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00
.byte 0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18, 0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xDE, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xE6, 0x66, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC3, 0xE7, 0xFF, 0xFF, 0xDB, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00
.byte 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xDB, 0xDB, 0xFF, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFF, 0xC3, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC3, 0xFF, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00
.byte 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00
.byte 0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00
.byte 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xDB, 0xDB, 0xFF, 0x66, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0xC3, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00
.byte 0x00, 0x00, 0xCC, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x10, 0x38, 0x6C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xCC, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x60, 0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x00, 0x00, 0x00
.byte 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0xC6, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
.byte 0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
.byte 0x18, 0x30, 0x60, 0x00, 0xFE, 0x66, 0x60, 0x7C, 0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x3B, 0x1B, 0x7E, 0xD8, 0xDC, 0x77, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC, 0xFE, 0xCC, 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00
.byte 0x00, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x18, 0x18, 0x7E, 0xC3, 0xC0, 0xC0, 0xC0, 0xC3, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xC3, 0x66, 0x3C, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x62, 0x66, 0x6F, 0x66, 0x66, 0x66, 0xF3, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x0E, 0x1B, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00
.byte 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x0C, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x18, 0x30, 0x60, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00
.byte 0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xC0, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x60, 0xCE, 0x9B, 0x06, 0x0C, 0x1F, 0x00, 0x00
.byte 0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xCE, 0x96, 0x3E, 0x06, 0x06, 0x00, 0x00
.byte 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6C, 0xD8, 0x6C, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6C, 0x36, 0x6C, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44
.byte 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA
.byte 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
.byte 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0
.byte 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F
.byte 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8, 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xD8, 0xCC, 0xC6, 0xC6, 0xC6, 0xCC, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xDB, 0xDB, 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
.byte 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x70, 0xD8, 0x30, 0x60, 0xC8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

View file

@ -1,227 +0,0 @@
#define BASE_ADDRESS 0x10000
#define FILE_SIZE (0x4000+0x40000)
header_start:
.ascii "XBEH"
// digital signature
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long BASE_ADDRESS // base address
.long headers_end - header_start // size of headers
.long FILE_SIZE+1024 // size of image
.long header_end - header_start // size of image header
.long 0 // time date stamp *unimportant*
.long certificate // certificate address
.long 1 // number of section headers
.long section_headers // section headers address
.long 0 // initialization flags
.long 0x11100 ^ 0xA8FC57AB // entry point address XOR key **GAS ISSUE: "entry" won't work**
.long 0x18000 // thread local storage address
.long 0 // size of stack commit (PE copy) *unimportant*
.long 0 // size of heap reserve (PE copy) *unimportant*
.long 0 // size of heap commit (PE copy) *unimportant*
.long 0 // original base address (PE copy) *unimportant*
.long 0 // original size of image (PE copy)*unimportant*
.long 0 // original checksum (PE copy) *unimportant*
.long 0 // original time stamp (PE copy) *unimportant*
.long normalname // debug path name address *unimportant*
.long normalname // debug file name address *unimportant*
.long unicodename // debug unicode file name address *unimportant*
.long 0x11000 ^ 0x5B6D40B6 // kernel image thunk address XOR key **GAS ISSUE: see above**
.long 0 // non-kernel import directory address
.long 0 // number of library versions *unimportant*
.long 0 // library versions address *unimportant*
.long 0 // kernel library version address *unimportant*
.long 0 // XAPI library address *unimportant*
.long logo // logo bitmap address *unimportant*
.long logo_end-logo // logo bitmap size *unimportant*
header_end:
certificate:
.long certificate_end - certificate // size of certificate
.long 0 // time date stamp *unimportant*
.long 0 // title id *unimportant?*
// title name (unicode string, 40 chars) *unimportant, but beautiful*
unicodename:
.word 'L','i','n','u','x',0,0,0,0,0,0
normalname:
.word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.word 0,0,0,0,0,0,0,0,0,0,0,0,0
// alternate title ids
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long 0xC0000005
.long 0x80000007 // game regions: all; don't delete eepromkey
.long -1 // game ratings
.long 0 // disk number
.long 0 // version
// LAN key
.long 0,0,0,0
// signature key
.long 0,0,0,0
// 16 title alternate signature keys
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
certificate_end:
section_headers:
// .long 0x16 // flags: RO_HEAD_PAGE, EXECUTABLE, PRELOAD
.long 0x07 // flags: WRITABLE, EXECUTABLE, PRELOAD
.long section_1_start // virtual address
.long FILE_SIZE // virtual size
.long 0x1000 // file pointer to raw data
.long FILE_SIZE // size of raw data
.long section_name // address of section name
.long 0 // unknown
.long rc1 // head shared page reference count address *not NULL important*
.long rc2 // tail shared page reference count address *not NULL important*
// unknown
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.byte 0,0,0,0
section_headers_end:
rc1:
.word 0
rc2:
.word 0
section_name:
.byte '.','t','e','x','t',0
.align 4
logo:
// "Linux"
.byte 0x52, 0x00, 0x13, 0x73, 0xB3, 0xF3, 0xF5, 0xE3
.byte 0xD3, 0xE3, 0x63, 0x03, 0x03, 0x03, 0x03, 0x07
.byte 0x03, 0x03, 0x13, 0x43, 0x33, 0x13, 0x03, 0x96
.byte 0x00, 0x9A, 0x00, 0x03, 0x03, 0x13, 0x33, 0xB3
.byte 0xF3, 0xF3, 0xF3, 0x93, 0x43, 0x23, 0x13, 0x03
.byte 0x03, 0x09, 0x03, 0x03, 0x73, 0x93, 0x83, 0x33
.byte 0x13, 0x03, 0x92, 0x00, 0x9A, 0x00, 0x03, 0x03
.byte 0x03, 0x23, 0x63, 0xF5, 0xE3, 0x73, 0x43, 0x23
.byte 0x13, 0x03, 0x03, 0x09, 0x03, 0x03, 0x73, 0x93
.byte 0x83, 0x33, 0x13, 0x03, 0x03, 0x09, 0x03, 0x05
.byte 0x09, 0x0B, 0x05, 0x03, 0x03, 0x05, 0x05, 0x07
.byte 0x03, 0x0B, 0x05, 0x9A, 0x00, 0x03, 0x03, 0x03
.byte 0x13, 0x63, 0xF5, 0xE3, 0x73, 0x43, 0x23, 0x03
.byte 0x03, 0x0B, 0x03, 0x13, 0x33, 0x53, 0x53, 0x33
.byte 0x13, 0x03, 0x03, 0x05, 0x03, 0x03, 0x05, 0x03
.byte 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
.byte 0x03, 0x03, 0x03, 0x03, 0x03, 0x05, 0x03, 0x03
.byte 0x03, 0x03, 0x05, 0x03, 0x03, 0x05, 0x03, 0x03
.byte 0x03, 0x9A, 0x00, 0x03, 0x03, 0x03, 0x13, 0x53
.byte 0xF5, 0xD3, 0x73, 0x33, 0x13, 0x03, 0x05, 0x03
.byte 0x05, 0x03, 0x03, 0x23, 0x33, 0x33, 0x33, 0x23
.byte 0x23, 0x23, 0x23, 0x35, 0x23, 0x33, 0x33, 0x33
.byte 0x23, 0x05, 0x03, 0x13, 0x35, 0x33, 0x23, 0x13
.byte 0x25, 0x23, 0x33, 0x23, 0x13, 0x13, 0x33, 0x33
.byte 0x35, 0x33, 0x23, 0x23, 0x33, 0x33, 0x13, 0x03
.byte 0x03, 0x9A, 0x00, 0x03, 0x03, 0x03, 0x03, 0x53
.byte 0xF5, 0xD3, 0x73, 0x33, 0x13, 0x03, 0x03, 0x03
.byte 0x05, 0x03, 0x03, 0x53, 0x83, 0x73, 0x43, 0x23
.byte 0x13, 0x63, 0x93, 0xD3, 0xF3, 0xE3, 0xB3, 0xB3
.byte 0xA3, 0xE3, 0xA3, 0x43, 0x13, 0x23, 0x93, 0xF3
.byte 0xE3, 0xF3, 0x83, 0x43, 0x83, 0x93, 0xD3, 0xF3
.byte 0x93, 0x13, 0x33, 0xB3, 0xF7, 0xB3, 0x43, 0xA3
.byte 0xF3, 0xE3, 0x53, 0x13, 0x03, 0x9A, 0x00, 0x03
.byte 0x03, 0x03, 0x03, 0x53, 0xF5, 0xD3, 0x63, 0x33
.byte 0x13, 0x03, 0x05, 0x03, 0x03, 0x03, 0x63, 0x83
.byte 0x53, 0x93, 0x83, 0x33, 0x23, 0x13, 0x23, 0xD3
.byte 0xF3, 0xF3, 0xD3, 0x53, 0x33, 0xC3, 0xF3, 0xD3
.byte 0x43, 0x33, 0x53, 0x93, 0xF3, 0xF3, 0xA3, 0x43
.byte 0x23, 0x73, 0xF5, 0xC3, 0x33, 0x23, 0x23, 0xA3
.byte 0xF5, 0x83, 0x43, 0x73, 0xD3, 0x63, 0x23, 0x13
.byte 0x03, 0x9A, 0x00, 0x03, 0x03, 0x03, 0x03, 0x53
.byte 0xF5, 0xD3, 0x63, 0x33, 0x13, 0x03, 0x03, 0x03
.byte 0x05, 0x13, 0x83, 0x43, 0x63, 0x93, 0x83, 0x53
.byte 0x33, 0x13, 0x33, 0xC3, 0xF3, 0xF3, 0x83, 0x53
.byte 0x33, 0xA3, 0xF3, 0xF3, 0x73, 0x33, 0x23, 0x43
.byte 0xE3, 0xF3, 0xB3, 0x53, 0x33, 0x83, 0xF5, 0xC3
.byte 0x53, 0x33, 0x23, 0x43, 0xD3, 0xF3, 0xE3, 0x83
.byte 0xD3, 0x83, 0x33, 0x23, 0x13, 0x03, 0x9A, 0x00
.byte 0x03, 0x03, 0x03, 0x03, 0x53, 0xF5, 0xD3, 0x63
.byte 0x33, 0x13, 0x03, 0x05, 0x03, 0x73, 0x33, 0x43
.byte 0x33, 0x73, 0x93, 0x83, 0x53, 0x33, 0x13, 0x23
.byte 0xB3, 0xF3, 0xF3, 0x83, 0x53, 0x33, 0x93, 0xF3
.byte 0xF3, 0x83, 0x33, 0x23, 0x43, 0xF3, 0xF3, 0xB3
.byte 0x53, 0x33, 0x93, 0xF5, 0xC3, 0x53, 0x33, 0x13
.byte 0x23, 0x73, 0xF5, 0xE3, 0xC3, 0x53, 0x33, 0x23
.byte 0x03, 0x03, 0x9A, 0x00, 0x03, 0x03, 0x03, 0x13
.byte 0x53, 0xF5, 0xD3, 0x63, 0x33, 0x13, 0x03, 0x03
.byte 0x03, 0x03, 0xA3, 0x53, 0x23, 0x53, 0x93, 0x93
.byte 0x83, 0x53, 0x33, 0x13, 0x23, 0xC3, 0xF3, 0xE3
.byte 0x83, 0x43, 0x23, 0x93, 0xF3, 0xF3, 0x83, 0x43
.byte 0x23, 0x43, 0xF5, 0xA3, 0x53, 0x33, 0x73, 0xF5
.byte 0xC3, 0x53, 0x33, 0x13, 0x13, 0x23, 0xB3, 0xF3
.byte 0xF3, 0xA3, 0x53, 0x33, 0x13, 0x03, 0x03, 0x9A
.byte 0x00, 0x03, 0x03, 0x03, 0x03, 0x53, 0xF5, 0xD3
.byte 0x73, 0x33, 0x13, 0x03, 0x03, 0x03, 0x03, 0xB3
.byte 0x63, 0x33, 0x63, 0x93, 0x93, 0x73, 0x53, 0x33
.byte 0x13, 0x23, 0xC3, 0xF3, 0xE3, 0x73, 0x43, 0x23
.byte 0x93, 0xF3, 0xF3, 0x83, 0x43, 0x23, 0x43, 0xF5
.byte 0xA3, 0x53, 0x33, 0x73, 0xF3, 0xF3, 0xC3, 0x53
.byte 0x33, 0x13, 0x13, 0x13, 0x73, 0xF3, 0xF3, 0xE3
.byte 0x73, 0x33, 0x13, 0x03, 0x03, 0x9A, 0x00, 0x03
.byte 0x03, 0x03, 0x03, 0x53, 0xF5, 0xD3, 0x63, 0x33
.byte 0x13, 0x03, 0x03, 0x03, 0x33, 0xE3, 0x63, 0x43
.byte 0x83, 0x93, 0x83, 0x73, 0x73, 0x53, 0x13, 0x23
.byte 0xC3, 0xF3, 0xD3, 0x73, 0x33, 0x13, 0x93, 0xF3
.byte 0xF3, 0x73, 0x43, 0x23, 0x43, 0xF5, 0xA3, 0x53
.byte 0x23, 0x73, 0xF5, 0xC3, 0x53, 0x33, 0x13, 0x03
.byte 0x03, 0x83, 0xC3, 0xF3, 0xF3, 0xC3, 0x43, 0x23
.byte 0x03, 0x03, 0x9A, 0x00, 0x05, 0x03, 0x03, 0x53
.byte 0xF5, 0xE3, 0x73, 0x33, 0x13, 0x03, 0x05, 0x83
.byte 0xF3, 0x73, 0x53, 0x93, 0x93, 0x83, 0x73, 0x83
.byte 0x43, 0x23, 0x33, 0xC3, 0xF3, 0xD3, 0x73, 0x43
.byte 0x23, 0x93, 0xF3, 0xF3, 0x73, 0x43, 0x23, 0x43
.byte 0xF5, 0xA3, 0x53, 0x33, 0x83, 0xF5, 0xC3, 0x53
.byte 0x33, 0x13, 0x03, 0x63, 0xE3, 0x73, 0xB3, 0xF5
.byte 0x83, 0x33, 0x13, 0x03, 0x9A, 0x00, 0x05, 0x03
.byte 0x03, 0x63, 0xF5, 0xF3, 0x73, 0x33, 0x13, 0x03
.byte 0x23, 0x73, 0xF3, 0xF3, 0x73, 0x63, 0x93, 0x93
.byte 0x83, 0x83, 0x73, 0x33, 0x23, 0x23, 0xD3, 0xF3
.byte 0xD3, 0x63, 0x33, 0x13, 0x93, 0xF3, 0xF3, 0x63
.byte 0x33, 0x23, 0x43, 0xF3, 0xF3, 0xB3, 0x53, 0x43
.byte 0xA3, 0xF5, 0xC3, 0x53, 0x33, 0x03, 0x23, 0xB3
.byte 0x83, 0x43, 0x63, 0xD3, 0xF3, 0xE3, 0x53, 0x23
.byte 0x13, 0x9E, 0x00, 0x13, 0x63, 0x83, 0xC3, 0xF3
.byte 0xF5, 0xA3, 0x83, 0x73, 0x73, 0xC3, 0xF7, 0x83
.byte 0x53, 0x83, 0x93, 0x93, 0x83, 0x53, 0x33, 0x53
.byte 0x83, 0xF5, 0xE3, 0xA3, 0x53, 0x63, 0xD3, 0xF3
.byte 0xF3, 0xA3, 0x63, 0x23, 0x23, 0x93, 0xF3, 0xF3
.byte 0xB3, 0x93, 0xB3, 0xF3, 0xF3, 0xE3, 0x83, 0x53
.byte 0x73, 0xA3, 0xF3, 0xC3, 0x63, 0x73, 0xB3, 0xF5
.byte 0xC3, 0x63, 0x23, 0x9E, 0x00, 0x13, 0x63, 0x75
.byte 0x83, 0x93, 0x83, 0x83, 0x73, 0x63, 0x73, 0x73
.byte 0x83, 0x83, 0x93, 0x63, 0x43, 0x43, 0x63, 0x63
.byte 0x53, 0x33, 0x23, 0x43, 0x63, 0x73, 0x83, 0x93
.byte 0x83, 0x53, 0x63, 0x83, 0x83, 0x93, 0x93, 0x53
.byte 0x23, 0x13, 0x33, 0x73, 0xA3, 0xA3, 0x73, 0x43
.byte 0x83, 0xA3, 0x93, 0x73, 0x43, 0x73, 0x73, 0x73
.byte 0x93, 0x53, 0x53, 0x73, 0x83, 0x93, 0x93, 0x63
.byte 0x23, 0x9A, 0x00, 0x03, 0x03, 0x03, 0x13, 0x23
.byte 0x33, 0x43, 0x43, 0x33, 0x23, 0x13, 0x13, 0x23
.byte 0x23, 0x35, 0x33, 0x23, 0x23, 0x23, 0x33, 0x33
.byte 0x23, 0x13, 0x13, 0x13, 0x23, 0x33, 0x33, 0x33
.byte 0x23, 0x13, 0x23, 0x33, 0x33, 0x33, 0x23, 0x13
.byte 0x13, 0x13, 0x23, 0x33, 0x33, 0x33, 0x35, 0x45
.byte 0x33, 0x23, 0x13, 0x13, 0x23, 0x23, 0x23, 0x23
.byte 0x23, 0x33, 0x33, 0x33, 0x23, 0x13, 0x4E, 0x00
logo_end:
.align 4
headers_end:

View file

@ -1,643 +0,0 @@
// Xbox Linux XBE Bootloader
//
// Copyright (C) 2002 Michael Steil & anonymous
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// The latest version of the GPL can be retrieved at:
// http://www.gnu.org/licenses/gpl.html .
//
// Xbox is a trademark or registered trademark of Microsoft Corporation.
// No relationship between the author(s) and Microsoft Corporation exists or is
// implied.
// Constants
// Size of a page on x86
#define PAGE_SIZE 4096
// Win32 read/write protection mode. x86 has no flag for executability.
#define PAGE_READWRITE 4
// Final address of Linux kernel in RAM
#define KERNEL_ADDRESS 0x00100000
// Minimum physical address at which the kernel can reside temporarily
#define MIN_KERNEL_ADDRESS KERNEL_ADDRESS
// Memory reserved to the kernel (1 MB at the moment)
#define KERNEL_MAX_SIZE 0x00100000 // 1MB maximum Kernel for Cromwell
// Location of kernel in RAM
#define KERNEL_RAM_ADDRESS 0x03A00000
// Size of memory on a retail XBOX unit
#define RETAIL_RAM_SIZE 0x04000000
// Reserve pages in address space
#define MEM_RESERVE 0x00002000
// Commit physical memory to pages
#define MEM_COMMIT 0x00001000
// CR0 bit to block write-through
#define CR0_DISABLE_WRITE_THROUGH 0x20000000
// CR0 bit to disable caching
#define CR0_DISABLE_CACHE 0x40000000
// CR0 bit to enable paging
#define CR0_ENABLE_PAGING 0x80000000
#define FRAMEBUFFER 0xF0040240
#define TEXTBUFFER (FRAMEBUFFER + 80 * 640 * 4)
//#define DebugOut
/* located within bootsect space (copied from arch/i386/setup.c) */
/* originally defined mostly in arch/i386/kernel/setup.c and head.S */
PARAM = 0
SCREEN_INFO = PARAM+0
EXT_MEM_K = PARAM+2
CL_MAGIC = PARAM+0x20
CL_OFFSET = PARAM+0x22
ALT_MEM_K = PARAM+0x01e0
APM_BIOS_INFO = PARAM+0x0040
DRIVE_INFO = PARAM+0x0080
SYS_DESC_TABLE = PARAM+0x00A0
SETUP_SECTS = PARAM+0x01F1
MOUNT_ROOT_RDO = PARAM+0x01F2
SYSSIZE = PARAM+0x01F4
RAMDISK_FLAGS = PARAM+0x01F8
ORIG_ROOT_DEV = PARAM+0x01FC
AUX_DEVICE_INFO = PARAM+0x01FF
/* located within and following the setup space: */
LOADER_TYPE = PARAM+0x0210
LOAD_FLAGS = PARAM+0x0211
KERNEL_START = PARAM+0x0214
INITRD_START = PARAM+0x0218
INITRD_SIZE = PARAM+0x021C
COMMAND_LINE = PARAM+0x0800
REL_COMMAND_LINE = 0x0800
PARAM_CURSOR_POS = PARAM+0x00
PARAM_VIDEO_PAGE = PARAM+0x04
PARAM_VIDEO_MODE = PARAM+0x06
PARAM_VIDEO_COLS = PARAM+0x07
PARAM_VIDEO_EGA_BX = PARAM+0x0a
PARAM_VIDEO_LINES = PARAM+0x0e
PARAM_HAVE_VGA = PARAM+0x0f
PARAM_FONT_POINTS = PARAM+0x10
PARAM_LFB_WIDTH = PARAM+0x12
PARAM_LFB_HEIGHT = PARAM+0x14
PARAM_LFB_DEPTH = PARAM+0x16
PARAM_LFB_BASE = PARAM+0x18
PARAM_LFB_SIZE = PARAM+0x1c
PARAM_LFB_LINELENGTH = PARAM+0x24
PARAM_LFB_COLORS = PARAM+0x26
PARAM_VESAPM_SEG = PARAM+0x2e
PARAM_VESAPM_OFF = PARAM+0x30
PARAM_LFB_PAGES = PARAM+0x32
.code32
.text
// This includes a minimal XBE header. It's not complete, i.e. software that wants
// to decode the header, such as "xbedump" (or probably Microsoft's certification
// tools) are likely to fail, but it is a valid header for the Xbox kernel.
#include "xbe.S"
.org 0x1000
section_1_start: // this should be 0x11000
// kernel thunk table
MmAllocateContiguousMemoryEx:
.long 0x80000000 + 166
MmGetPhysicalAddress:
.long 0x80000000 + 173
NtAllocateVirtualMemory:
.long 0x80000000 + 184
.long 0 // end of table
.org 0x1080
cromwellstart:
.long 0x3000 // Start of the ROM image
cromwellsize:
.long 0x00060000 // Size of the ROM image (this Value will be overwritten by Imagebld)
.org 0x1100
entry: // this should be 0x11100
.globl _start
.intel_syntax noprefix
_start:
#ifdef DebugOut
mov ebx, 0 // x position
mov ecx, 0 // y position
lea esi, text1
mov eax, MmAllocateContiguousMemoryEx
call strhexout
lea esi, text2
mov eax, MmGetPhysicalAddress
call strhexout
lea esi, text3
mov eax, NtAllocateVirtualMemory
call strhexout
lea esi, text_kernel
mov eax, offset kernel
call strhexout
#endif
// 1. use MmAllocateContiguousMemoryEx to allocate physical memory
// somewhere between 1 and 32 MB for the kernel
push ebx
push ecx
push PAGE_READWRITE
push 0
push RETAIL_RAM_SIZE / 2 - 1
push MIN_KERNEL_ADDRESS + (KERNEL_MAX_SIZE)
push (KERNEL_MAX_SIZE)
call dword ptr [MmAllocateContiguousMemoryEx]
mov [kernelram], eax
pop ecx
pop ebx
#ifdef DebugOut
push eax
lea esi, text_kernelram
call strhexout
pop eax // kernelram
#endif
// 3. MmGetPhysicalAddress that memory
push ebx
push ecx
push dword ptr [kernelram]
call dword ptr [MmGetPhysicalAddress]
mov [phys_kernelram], eax
pop ecx
pop ebx
#ifdef DebugOut
lea esi, text_phys_kernelram
call strhexout
#endif
// 2. put kernel there
// UWEI
push ecx
mov esi, offset kernel
mov edi, dword ptr [kernelram]
mov ecx, [cromwellsize]
rep movsb
pop ecx
// 4. use MmAllocateContiguousMemoryEx to allocate 4096 bytes of memory
// for the boot loader between 16 MB and 32 MB (virtual memory should
// be unallocated there)
push ebx
push ecx
push PAGE_READWRITE
push 16
push RETAIL_RAM_SIZE / 2
push RETAIL_RAM_SIZE / 4
push PAGE_SIZE
call dword ptr [MmAllocateContiguousMemoryEx]
mov [bootloaderram], eax
pop ecx
pop ebx
#ifdef DebugOut
lea esi, text_bootloaderram
call strhexout
#endif
// 5. use MmGetPhysicalAddress on that
push ebx
push ecx
push dword ptr [bootloaderram]
call dword ptr [MmGetPhysicalAddress]
mov [phys_bootloaderram], eax
pop ecx
pop ebx
#ifdef DebugOut
lea esi, text_phys_bootloaderram
call strhexout
#endif
// 6. use NtAllocateVirtualMemory to allocate virtual memory at that virtual address
// NtAllocateVirtualMemory(
// (PVOID*) &phys_bootloaderram,
// (ULONG) 0,
// (PULONG) PAGE_SIZE, *****BUG***** POINTER!!
// (ULONG) MEM_RESERVE | MEM_COMMIT,
// (ULONG) PAGE_READWRITE);
push ebx
push ecx
push PAGE_READWRITE
push MEM_RESERVE + MEM_COMMIT // sum = 3000
push offset ptr_PAGE_SIZE
push 0 // 0 is used when the caller determines address
push offset phys_bootloaderram
call dword ptr [NtAllocateVirtualMemory]
pop ecx
pop ebx
#ifdef DebugOut
lea esi, text_allocvirt
call strhexout
#endif
// 7. put a copy of the boot loader at both #4 and #6's memory
// Copy to #4
cld
mov esi, offset blentry
mov edi, [bootloaderram]
mov ecx, PAGE_SIZE / 4
rep movsb
// Copy to #6
// The phys_bootloaderram looks strange, but it's correct. It was made into
// a virtual address by NtAllocateVirtualMemory.
mov esi, offset blentry
mov edi, [phys_bootloaderram]
mov ecx, PAGE_SIZE / 4
rep movsb
// mov ebp, dword ptr [phys_pm_kernelram] // kernel
mov esi, dword ptr [phys_kernelram] // kernel information structure
mov edx, [phys_bootloaderram]; // we'll need it again later
mov ecx, edx;
sub ecx, offset blentry;
// construct jmp to new CS
mov eax, ecx
add eax, offset newloc
mov ebx, ecx
add ebx, offset ptr_newloc
mov [ebx], eax
add ebx, 0x80000000 // change physical page, too
mov [ebx], eax
jmp edx;
// this is the bootloader code
// ecx = ("blentry" in real memory) - (blentry in original memory)
// ebp = phys_pm_kernelram
// esi = phys_kernelram
blentry:
cli;
// turn off paging
mov eax, cr0
and eax, 0xFFFFFFFF - CR0_ENABLE_PAGING
mov cr0, eax
xor eax, eax // flush the TLB
mov cr3, eax
// setup
// put position if gdt into gdt_48_base
mov eax, ecx
add eax, offset bootloader_gdt
mov ebx, ecx
add ebx, offset gdt_48_base
mov [ebx], eax
// load new gdt/ldt/idt
mov eax, ecx
add eax, offset idt_48
lidt [eax]
mov eax, ecx
add eax, offset gdt_48
lgdt [eax]
xor eax, eax
lldt ax
// initialize segment registers
mov ax, 0x0010
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
// jmp to new location
.byte 0xea // = ljmp
ptr_newloc:
.long 0
.word 0x0008
newloc:
// copy the Cromwell to it's new position
mov edi, KERNEL_RAM_ADDRESS
mov ecx, KERNEL_MAX_SIZE
rep movsb
// Kill Interrupt Handler
cli
// Interrupt Handler Now Dead
//jmp newflash
// Jump into Cromwell & start Kernel
.byte 0xea // = ljmp
.long KERNEL_RAM_ADDRESS // Basically, jump to the first Byte in the Cromwell image...
.word 0x0008
newflash:
// flash the LEDs
// use this as debug code to check whether control reaches a certain point
#define LED_RED_C0 0x80
#define LED_RED_C1 0x40
#define LED_RED_C2 0x20
#define LED_RED_C3 0x10
#define LED_GREEN_C0 0x08
#define LED_GREEN_C1 0x04
#define LED_GREEN_C2 0x02
#define LED_GREEN_C3 0x01
mov dx, 0xc004
mov al, 0x20
out dx, al
mov dx, 0xc008
mov al, 8
out dx, al
mov dx, 0xc006
mov al, LED_RED_C0+LED_GREEN_C1+LED_RED_C2+LED_GREEN_C2
out dx, al
mov dx, 0xc000
in ax, dx
out dx, al
mov dx, 0xc002
mov al, 0x1a
out dx, al
mov eax, 1000000
l2:
dec eax
jne l2
mov dx, 0xc004
mov al, 0x20
out dx, al
mov dx, 0xc008
mov al, 7
out dx, al
mov dx, 0xc006
mov al, 1
out dx, al
mov dx, 0xc000
in ax, dx
out dx, al
mov dx, 0xc002
mov al, 0x1a
out dx, al
lx:
jmp lx
// taken from linux/arch/i386/boot/boot.S
// SS entry was added
.align 16
bootloader_gdt:
// 0000 (dummy)
.word 0, 0, 0, 0 // dummy
// // 0008 (TSS?)
// .word 0, 0, 0, 0 // unused
// 0008 (code segment)
.word 0xFFFF // 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 // base address = 0
.word 0x9A00 // code read/exec
.word 0x00CF // granularity = 4096, 386
// (+5th nibble of limit)
// 0010 (data segment)
.word 0xFFFF // 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 // base address = 0
.word 0x9200 // data read/write
.word 0x00CF // granularity = 4096, 386
// (+5th nibble of limit)
.align 8
idt_48:
.word 0 // idt limit = 0
.word 0, 0 // idt base = 0L
.align 8
gdt_48:
.word 0x8000 // GDT limit=2048, 256 entries
gdt_48_base:
.long 0 // GDT base
// call flash
//infinite:
// jmp infinite
strhexout:
push eax
call strout
pop eax
call hexout32
cr:
mov al, 0xa
jmp chrout
strout:
// esi: text
// ebx: x position (will be updated)
// ecx: y position (will be updated)
mov eax, 0
lodsb // char
test al,al
je charend
call chrout
jmp strout
charend:
ret
hexout32:
push eax
shr eax, 16
call hexout16
pop eax
and eax, 0xFFFF
hexout16:
push eax
mov al, ah
call hexout8
pop eax
hexout8:
push eax
shr al, 4
call hexout4
pop eax
and al, 0xF
hexout4:
cmp al, 10
jb hexoutd
add al, 'A' - 10
jmp chrout
hexoutd:
add al, '0'
chrout:
// eax: character
// ebx: x position (will be updated)
// ecx: y position (will be updated)
cmp al, 0x0a // lf?
jne nlf
mov ebx, 0
inc ecx
ret
nlf:
pusha
and eax, 0xff // avoid font overflow
shl eax, 4 // index to character
lea esi, font[eax]
mov eax, ebx // x position
shl eax, 5 // index to screen line
lea edi, TEXTBUFFER[eax]
mov eax, ecx // y position
mov ebx, 0xA000
mul ebx
add edi, eax
mov ecx, 16
fl1:
lodsb
push ecx
mov ecx, 8
fl2:
shl al, 1
push eax
mov eax, 0
jnc f2
dec eax
f2:
stosd
pop eax
loop fl2
add edi, 640*4 - 8*4
pop ecx
loop fl1
popa
// update cursor position
inc ebx
cmp ebx, 80
jb no1
mov bx, 0
inc cx
no1:
ret
text1:
.ascii "MmAllocateContiguousMemoryEx: 0x"
.byte 0
text2:
.ascii "MmGetPhysicalAddress: 0x"
.byte 0
text3:
.ascii "NtAllocateVirtualMemory: 0x"
.byte 0
text_kernel:
.ascii "kernel: 0x"
.byte 0
text_kernelram:
.ascii "kernelram: 0x"
.byte 0
text_phys_kernelram:
.ascii "phys_kernelram: 0x"
.byte 0
text_bootloaderram:
.ascii "bootloaderram: 0x"
.byte 0
text_phys_bootloaderram:
.ascii "phys_bootloaderram: 0x"
.byte 0
text_allocvirt:
.ascii "NtAllocateVirtualMemory(...) = 0x"
.byte 0
text_setup_sects:
.ascii "setup_sects: 0x"
.byte 0
//text_phys_pm_kernelram:
//.ascii "phys_pm_kernelram: 0x"
//.byte 0
ptr_PAGE_SIZE:
.long PAGE_SIZE
my_command_line:
.ascii "devfs=mount"
.byte 0
// Variables
.align 4
// Virtual address of the kernel's allocated physical memory
kernelram:
.long 0
// Physical address of kernelram
phys_kernelram:
.long 0
// Virtual address of the bootloaders's allocated physical memory
bootloaderram:
.long 0
// Physical address of bootloader _and_ virtual address of a second copy
phys_bootloaderram:
.long 0
//phys_pm_kernelram:
// .long 0
#include "font.S"
//.align 4096.
.org 0x3000
kernel:

View file

@ -1,3 +0,0 @@
subdir += ide pci video flash cpu usb
include $(TOPDIR)/Rules.make

View file

@ -1,4 +0,0 @@
O_TARGET := cputools.o microcode.o ioapic.o
include $(TOPDIR)/Rules.make

View file

@ -1,31 +0,0 @@
#define rdmsr(msr,val1,val2) \
__asm__ __volatile__("rdmsr" \
: "=a" (val1), "=d" (val2) \
: "c" (msr))
#define wrmsr(msr,val1,val2) \
__asm__ __volatile__("wrmsr" \
: /* no outputs */ \
: "c" (msr), "a" (val1), "d" (val2))
#define rdtsc(low,high) \
__asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
#define rdtscl(low) \
__asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx")
#define rdtscll(val) \
__asm__ __volatile__ ("rdtsc" : "=A" (val))
#define rdpmc(counter,low,high) \
__asm__ __volatile__("rdpmc" \
: "=a" (low), "=d" (high) \
: "c" (counter))
extern void intel_interrupts_on(void);
extern void cache_disable(void);
extern void cache_enable(void);
extern void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx);
void display_cpuid_update_microcode(void);
void setup_ioapic(void);

View file

@ -1,60 +0,0 @@
#include "boot.h"
#include "config.h"
#include "cpu.h"
extern void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
{
__asm__("pushl %%ebx\n\t"
"cpuid\n\t"
"movl %%ebx, %%esi\n\t"
"popl %%ebx\n\t"
: "=a" (*eax),
"=S" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "a" (op)
: "cc");
}
extern void intel_interrupts_on()
{
unsigned long low, high;
// printk("Disabling local apic...");
/* this is so interrupts work. This is very limited scope --
* linux will do better later, we hope ...
*/
rdmsr(0x1b, low, high);
low &= ~0x800;
wrmsr(0x1b, low, high);
}
extern void cache_disable(void)
{
unsigned int tmp;
/* Disable cache */
//printk("Disable Cache\n");
/* Write back the cache and flush TLB */
asm volatile ("movl %%cr0, %0\n\t"
"orl $0x40000000, %0\n\t"
"wbinvd\n\t"
"movl %0, %%cr0\n\t"
"wbinvd\n\t"
: "=r" (tmp) : : "memory");
}
extern void cache_enable(void)
{
unsigned int tmp;
asm volatile ("movl %%cr0, %0\n\t"
"andl $0x9fffffff, %0\n\t"
"movl %0, %%cr0\n\t"
:"=r" (tmp) : : "memory");
//printk("Enable Cache\n");
}

View file

@ -1,77 +0,0 @@
#include "boot.h"
#include "config.h"
#include "cpu.h"
struct ioapicreg {
unsigned int reg;
unsigned int value_low, value_high;
};
struct ioapicreg ioapicregvalues[] = {
#define ALL (0xff << 24)
#define NONE (0)
#define DISABLED (1 << 16)
#define ENABLED (0 << 16)
#define TRIGGER_EDGE (0 << 15)
#define TRIGGER_LEVEL (1 << 15)
#define POLARITY_HIGH (0 << 13)
#define POLARITY_LOW (1 << 13)
#define PHYSICAL_DEST (0 << 11)
#define LOGICAL_DEST (1 << 11)
#define ExtINT (7 << 8)
#define NMI (4 << 8)
#define SMI (2 << 8)
#define INT (1 << 8)
/* mask, trigger, polarity, destination, delivery, vector */
{0x00, DISABLED, NONE},
{0x01, DISABLED, NONE},
{0x02, DISABLED, NONE},
{0x03, DISABLED, NONE},
{0x04, DISABLED, NONE},
{0x05, DISABLED, NONE},
{0x06, DISABLED, NONE},
{0x07, DISABLED, NONE},
{0x08, DISABLED, NONE},
{0x09, DISABLED, NONE},
{0x0a, DISABLED, NONE},
{0x0b, DISABLED, NONE},
{0x0c, DISABLED, NONE},
{0x0d, DISABLED, NONE},
{0x0e, DISABLED, NONE},
{0x0f, DISABLED, NONE},
{0x10, DISABLED, NONE},
{0x11, DISABLED, NONE},
{0x12, DISABLED, NONE},
{0x13, DISABLED, NONE},
{0x14, DISABLED, NONE},
{0x14, DISABLED, NONE},
{0x15, DISABLED, NONE},
{0x16, DISABLED, NONE},
{0x17, DISABLED, NONE},
};
void setup_ioapic(void)
{
int i;
unsigned long value_low, value_high;
unsigned long nvram = 0xfec00000;
volatile unsigned long *l;
struct ioapicreg *a = ioapicregvalues;
l = (unsigned long *) nvram;
for (i = 0; i < sizeof(ioapicregvalues) / sizeof(ioapicregvalues[0]);
i++, a++) {
l[0] = (a->reg * 2) + 0x10;
l[4] = a->value_low;
value_low = l[4];
l[0] = (a->reg *2) + 0x11;
l[4] = a->value_high;
value_high = l[4];
if ((i==0) && (value_low == 0xffffffff)) {
printk("IO APIC not responding.\n");
return;
}
printk("for IRQ, reg 0x%08x value 0x%08x 0x%08x\n",
a->reg, a->value_low, a->value_high);
}
}

View file

@ -1,341 +0,0 @@
/* microcode.c: Microcode update for PIII and later CPUS
*
*
*/
#include "boot.h"
#include "config.h"
#include "cpu.h"
struct microcode {
unsigned int hdrver;
unsigned int rev;
unsigned int date;
unsigned int sig;
unsigned int cksum;
unsigned int ldrver;
unsigned int pf;
unsigned int reserved[5];
unsigned int bits[500];
};
const unsigned int microcode_updates [] = {
/*
Copyright Intel Corporation, 1995, 96, 97, 98, 99, 2000, 2001.
These microcode updates are distributed for the sole purpose of
installation in the BIOS or Operating System of computer systems
which include a Genuine Intel microprocessor sold or distributed
to or by you. You are not authorized to use this material for
any other purpose.
*/
/* MU168608.inc */
0x00000001, 0x00000008, 0x05052000, 0x00000686,
0xea2b7b61, 0x00000001, 0x00000010, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x38709a5e, 0x7cbb9fcd, 0x46f2975c, 0xdf0a611a,
0x454f553d, 0x4dd783fc, 0x38b72f92, 0xe6cd7f96,
0xf57804bd, 0xf12c0d73, 0xafa105a2, 0x74073ece,
0xfa02d788, 0xd8a7bdd3, 0x2471c214, 0xcdcf7014,
0x0e6e693c, 0xbafbc7c1, 0xd765a8ca, 0x65b6cc40,
0x2ed8a24a, 0x2c1fcf0d, 0x7d73ba93, 0xcf0a98db,
0x3caea0c2, 0x49e601d9, 0x936c2fef, 0xc87dc94d,
0x1fef698e, 0xda05fa7b, 0x204f5b4e, 0x441cedfd,
0x09f63dcc, 0xf7cc7654, 0x2b69ecf9, 0x495d0ef9,
0x7679dac3, 0x7a4c0547, 0xb7adeed9, 0x29053d15,
0xcf0b21bd, 0x77204452, 0x99ba650b, 0x3d19d146,
0x150b0f41, 0xd7b5238f, 0xd02a8165, 0xd1270d1d,
0xf6d102bc, 0x198ab690, 0xed878dbf, 0x34c2ec98,
0x4c9bee07, 0x66ec11f1, 0xaa5202db, 0x4d2f2fc8,
0x4ba8194b, 0x569fbee6, 0x9016ef51, 0x8fe4062c,
0x90148cec, 0x5be3ddc4, 0xf04ff2c4, 0x5de8d897,
0x09b1d0b4, 0x9f83a4f7, 0x0cf74fdf, 0x3c02a388,
0xa2045a65, 0xbe469468, 0x03e4c532, 0x5f14280e,
0xb384e96b, 0xfdce24fc, 0x2458e3ea, 0x169dbd24,
0x71c8b3f3, 0x67e019af, 0xcda860c1, 0xe279acc0,
0x6bc10e92, 0xe51258ec, 0x4630c6d5, 0xfc260a15,
0xca8197db, 0x30aefd93, 0x789a7c9f, 0x1dbd5410,
0xd4e1c7a1, 0x309e8843, 0xd47f27ab, 0xf0c4a0d6,
0xe30a1e06, 0x3056c766, 0xb45c4d62, 0x3b8a2d43,
0x0b013cdc, 0x8b2163e8, 0x3027cc1b, 0xe4c4db4e,
0x89a26935, 0xaeab01f3, 0x46406071, 0xfe9ca870,
0x73c6b8e0, 0xd55517a0, 0x40672814, 0x28d9e205,
0xfd23b70b, 0x885e72ed, 0x41861524, 0xeb7f77b2,
0xea826a61, 0x06a47055, 0x83d71cfc, 0xb6b5cbb6,
0xeea709e3, 0x25b910bf, 0x64ef9e5a, 0xd048a5a3,
0x0ecae00e, 0x216700b2, 0xf51cc285, 0x107f4916,
0xb390e89e, 0x07efee47, 0x8eb3d423, 0x151e4c0c,
0xab7ebbdc, 0xe471757b, 0x717f586b, 0xaacd6c2a,
0xa0c63ad6, 0xde1feca6, 0x234e73d8, 0xfc302a04,
0x4119848a, 0xbc8c78d5, 0xf3bb6d22, 0x2adc091b,
0x3d6a50a6, 0x80d0806c, 0xe775d1b9, 0xa398ace3,
0x47a09e7d, 0x82e43ac0, 0xb3ae0953, 0x9e953074,
0x4964b471, 0x4a8bb0fd, 0x9e6a6e8e, 0xee971884,
0xc7f2e4cc, 0xdc1b7ff4, 0x0ba3d273, 0x7d37c53c,
0x27554173, 0x7865dc77, 0xb24f15c5, 0x90c00d9b,
0x0ddd4024, 0x65050eb7, 0xf833936d, 0xe93cd40a,
0xe31dd31f, 0xc990cca6, 0xaad5564a, 0xcb6c45b9,
0xb1a6ef0b, 0xbac07112, 0xddbe22b2, 0xa01f1135,
0x0562493a, 0xb3f2f526, 0xd414512f, 0x5d945ebe,
0x0a8c95f1, 0xc214aa4d, 0x5006a179, 0xdd57b9bf,
0x92cc0d68, 0x29556e76, 0xbe68e6a4, 0x5dd7cedc,
0x2606954f, 0xb1168ed2, 0xbc7f4b32, 0x1cd43eee,
0x7f7e1f59, 0xdacd550e, 0x8e7c4adb, 0xd1b6af9e,
0x4abc5f32, 0x81181214, 0xc364896c, 0xc56c4a08,
0xd56aa244, 0x936f0be3, 0x3d0c967b, 0x1578d76a,
0x7cb10003, 0xdf0e8bad, 0x24bc9534, 0x4fbf3524,
0x7052039c, 0x6edb0691, 0x2f10c885, 0xd5adb704,
0x11ff9b52, 0xd6614cf1, 0x1ab2b79f, 0x9c4e93f2,
0x49e3431c, 0x6b80635f, 0x233912ad, 0x05168de1,
0x79e18bd7, 0x4d9d0ce4, 0x1e1d93f7, 0x041c93ca,
0x7109b31c, 0x98af2848, 0x012fd82e, 0xc134e4b1,
0x73cbf75a, 0xbc2ac259, 0xeb5f1138, 0xed0038a1,
0xa75bbad0, 0x9698ef09, 0x37b21e97, 0xe7d971e9,
0x3184de0a, 0x1d64395d, 0x005a6d27, 0xf26dfc59,
0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631,
0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a,
0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f,
0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038,
0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c,
0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea,
0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7,
0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed,
0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce,
0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1,
0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643,
0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2,
0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95,
0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708,
0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550,
0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e,
0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300,
0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06,
0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226,
0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff,
0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f,
0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa,
0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900,
0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282,
0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5,
0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21,
0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f,
0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b,
0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a,
0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb,
0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1,
0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8,
0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18,
0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d,
0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429,
0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b,
0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879,
0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950,
0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95,
0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61,
0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff,
0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9,
0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44,
0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d,
0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8,
0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5,
0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276,
0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d,
0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777,
0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758,
0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f,
0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60,
0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb,
0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef,
0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d,
0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89,
0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81,
0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8,
0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0,
0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007,
0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c,
0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6,
0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75,
0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116,
0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e,
0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec,
/* MU168a01.inc */
0x00000001, 0x00000001, 0x11022000, 0x0000068a,
0x80fc9e3b, 0x00000001, 0x00000010, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x4efad552, 0x58a399f1, 0xf144f845, 0xfdb9117d,
0xb230677d, 0x1136f756, 0x8298a1b2, 0xb0c9cffc,
0x1e77875e, 0x2ea286ab, 0x6943a0b5, 0x41e37874,
0xfad4205d, 0xbc2d4993, 0xe5ac11e8, 0xa81a4aa8,
0x977a1e24, 0xd78cb1a7, 0xea9b7600, 0x280582ee,
0x04779e3e, 0x4af7afda, 0xeba0b976, 0x40f8ed1c,
0x9801c81d, 0xf500eb15, 0x74eb0918, 0x9b17c81f,
0x9d5dd38f, 0x17410757, 0xf843bed3, 0x2c401670,
0x6a428a9d, 0x28640d65, 0x35840c58, 0xcae15773,
0xcad83b47, 0x304765ea, 0x36da3de4, 0xaca34c0f,
0x61950b2a, 0x13ff21a5, 0x0817c1bb, 0x7e68e7a3,
0x89d484f7, 0xa2c84945, 0xbdd500eb, 0x0f7aaaef,
0x43b3cc4d, 0x55aaf9b2, 0xb8e9831f, 0xf093b0b9,
0x8266e028, 0x5242bbd4, 0xccd1f798, 0x385ee185,
0x15b897df, 0xedcc4e3e, 0x5028068b, 0xe3fc6555,
0x24c2ded3, 0xf9ddf6aa, 0x1256f316, 0x21829113,
0x17bd6a35, 0x252bdbdf, 0x9d356e62, 0xe02c900a,
0xa3f04a7d, 0xd607feeb, 0xb2938296, 0x63192310,
0x0aa601be, 0xe75ba498, 0xe844f6cc, 0xd9016ef6,
0x0ee53a7b, 0x4109ef16, 0x06f14b3a, 0x28185283,
0x97abaed9, 0xb6aaf076, 0xdb485b2d, 0x64213aa4,
0xd95491d1, 0x79495ede, 0x0f6d13d2, 0x409172b3,
0x71ff4426, 0x39482f22, 0x7411a8a8, 0x1d33b47f,
0xd1b42e84, 0xec7754cf, 0x89116c0f, 0x2c09c658,
0x99c8564f, 0x6b901f71, 0x83a077bd, 0xd50ac9fe,
0x53427f66, 0x93447a6a, 0xa72bfaf2, 0x33e743e8,
0x240588c1, 0xd74f75fb, 0xbf90f7a5, 0x75c3c8a2,
0x9d0c5193, 0x43b92dd1, 0x2c00a47a, 0xfffce742,
0x5d3ac1fa, 0xcdc46584, 0x712af8c7, 0x3733fe09,
0xbb301419, 0x2bb6a944, 0x3edd7c53, 0x31157d4a,
0xba14f3a0, 0xa385a286, 0xa6ac6f44, 0xb09ee00a,
0x4fb68608, 0x5eba43d6, 0xeddde198, 0x688e46eb,
0x4f4cef08, 0xd3dd5f9d, 0x8c0d995b, 0xb1688d6d,
0x40f050f3, 0x064f8c26, 0x2acbc04b, 0xe3be1052,
0x81765ee9, 0x38ec4036, 0x4aebe9e4, 0x700aee4d,
0x0ddee69f, 0x32a8240c, 0xf1aadda5, 0x79d64bf0,
0x79bca80b, 0x42ba8186, 0x5093b355, 0xc6bc148a,
0x60bbbcf0, 0x58843416, 0x68fe124e, 0x551551b5,
0x2ee3310b, 0x3fe684e4, 0xd2669d2f, 0x6d32a6ec,
0x3c038661, 0xdfce797f, 0xb44f91b9, 0x6b054e2c,
0x6c8a55b0, 0x53d4f5cf, 0xa9ef5cc9, 0x6a1497e3,
0xdad943af, 0x7ac80ff7, 0x0a233ada, 0xdd162f79,
0x654e8707, 0x6e0d72dc, 0xa7f16610, 0x64af2199,
0x43cbc05a, 0xa082d85a, 0xa0ecc319, 0xed5fb102,
0x50e03123, 0x1e691374, 0x76cca719, 0x96a54140,
0xe637f7ac, 0x0bdceb2c, 0x2509562e, 0xdc493727,
0x9ae44e2b, 0xbe7c82e6, 0xdd903312, 0x16182680,
0xab131706, 0x00753d5a, 0x4f018f8a, 0x768bbd06,
0xda089985, 0x9ec0bf68, 0xcf0ca6d6, 0xef21a479,
0x10f990bb, 0x976257b1, 0x448acbd0, 0xd6a49e41,
0x146a9f84, 0x1c462ffe, 0xc1e13fc2, 0x33a89da1,
0xefe418ba, 0x2157e31e, 0xc9dab388, 0x7a5175f7,
0x8fca565c, 0x3badf7fa, 0xb6b3ad3c, 0xcdc7c3db,
0x75c1db40, 0x9f93463f, 0x869e7c18, 0xe3841a98,
0x47f4b382, 0x5b708e12, 0xb704f263, 0x0977410d,
0x510dad8c, 0x6e6e5abb, 0x523171ed, 0x0641bebd,
0x03f8ab45, 0xffb1561a, 0xbac7c413, 0x893143e7,
0x78f8702e, 0xf3a1a5dc, 0x154f9e24, 0xecee7df8,
0x887b465c, 0x31ea2f2d, 0x58e06b7f, 0x3e53c9d3,
0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631,
0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a,
0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f,
0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038,
0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c,
0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea,
0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7,
0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed,
0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce,
0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1,
0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643,
0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2,
0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95,
0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708,
0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550,
0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e,
0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300,
0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06,
0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226,
0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff,
0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f,
0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa,
0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900,
0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282,
0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5,
0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21,
0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f,
0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b,
0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a,
0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb,
0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1,
0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8,
0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18,
0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d,
0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429,
0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b,
0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879,
0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950,
0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95,
0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61,
0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff,
0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9,
0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44,
0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d,
0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8,
0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5,
0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276,
0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d,
0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777,
0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758,
0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f,
0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60,
0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb,
0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef,
0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d,
0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89,
0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81,
0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8,
0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0,
0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007,
0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c,
0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6,
0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75,
0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116,
0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e,
0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec,
};
void display_cpuid_update_microcode(void)
{
unsigned int eax, ebx, ecx, edx;
unsigned int pf, rev, sig, val[2];
unsigned int x86_model, x86_family, i;
struct microcode *m;
int found = 0 ;
/* cpuid sets msr 0x8B iff a microcode update has been loaded. */
wrmsr(0x8B, 0, 0);
cpuid(1, &eax, &ebx, &ecx, &edx);
rdmsr(0x8B, val[0], rev);
x86_model = (eax >>4) & 0x0f;
x86_family = (eax >>8) & 0x0f;
sig = eax;
pf = 0;
if ((x86_model >= 5)||(x86_family>6)) {
rdmsr(0x17, val[0], val[1]);
pf = 1 << ((val[1] >> 18) & 7);
}
// printk("\n\n");
// printk("microcode_info: sig = 0x%08x pf=0x%08x rev = 0x%08x\n",sig, pf, rev);
m = (struct microcode *)microcode_updates;
// We have 2 microocde Tables
for(i = 0; i < 2; i++) {
if ((m[i].sig == sig) && (m[i].pf == pf)) {
wrmsr(0x79, (unsigned int)&m[i].bits, 0);
__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
rdmsr(0x8B, val[0], val[1]);
//printk("microcode updated from revision %d to %d\n", rev, val[1]);
found = 1;
}
}
// if (found == 0) printk("No Valid Microcode Update for this processor found\n")
}

View file

@ -1,416 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "boot.h"
#include "BootFlash.h"
#include <stdio.h>
// gets device ID, sets pof up accordingly
// returns true if device okay or false for unrecognized device
bool BootFlashGetDescriptor( OBJECT_FLASH *pof, KNOWN_FLASH_TYPE * pkft )
{
bool fSeen=false;
BYTE baNormalModeFirstTwoBytes[2];
int nTries=0;
int nPos=0;
pof->m_fIsBelievedCapableOfWriteAndErase=true;
pof->m_szAdditionalErrorInfo[0]='\0';
baNormalModeFirstTwoBytes[0]=pof->m_pbMemoryMappedStartAddress[0];
baNormalModeFirstTwoBytes[1]=pof->m_pbMemoryMappedStartAddress[1];
while(nTries++ <2) { // first we try 29xxx method, then 28xxx if that failed
if(nTries!=1) { // 29xxx protocol
// make sure the flash state machine is reset
pof->m_pbMemoryMappedStartAddress[0x5555]=0xf0;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xf0;
// read flash ID
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0x90;
pof->m_bManufacturerId=pof->m_pbMemoryMappedStartAddress[0];
pof->m_bDeviceId=pof->m_pbMemoryMappedStartAddress[1];
pof->m_pbMemoryMappedStartAddress[0x5555]=0xf0;
pof->m_fDetectedUsing28xxxConventions=false; // mark the flash object as representing a 28xxx job
} else { // 28xxx protocol, seen on Sharp
// make sure the flash state machine is reset
pof->m_pbMemoryMappedStartAddress[0x5555]=0xff;
// read flash ID
pof->m_pbMemoryMappedStartAddress[0x5555]=0x90;
pof->m_bManufacturerId=pof->m_pbMemoryMappedStartAddress[0];
pof->m_pbMemoryMappedStartAddress[0x5555]=0x90;
pof->m_bDeviceId=pof->m_pbMemoryMappedStartAddress[1];
pof->m_pbMemoryMappedStartAddress[0x5555]=0xff;
pof->m_fDetectedUsing28xxxConventions=true; // mark the flash object as representing a 28xxx job
}
if(
(baNormalModeFirstTwoBytes[0]!=pof->m_bManufacturerId) ||
(baNormalModeFirstTwoBytes[1]!=pof->m_pbMemoryMappedStartAddress[1])
) nTries=2; // don't try any more if we got some result the first time
} // while
// interpret device ID info
{
bool fMore=true;
while(fMore) {
if(!pkft->m_bManufacturerId) {
fMore=false; continue;
}
if((pkft->m_bManufacturerId == pof->m_bManufacturerId) &&
(pkft->m_bDeviceId == pof->m_bDeviceId)
) {
fSeen=true;
fMore=false;
nPos+=sprintf(&pof->m_szFlashDescription[nPos], "%s (%dK)", pkft->m_szFlashDescription, pkft->m_dwLengthInBytes/1024);
pof->m_dwLengthInBytes = pkft->m_dwLengthInBytes;
if(pof->m_fDetectedUsing28xxxConventions) {
int n=0;
// detect master lock situation
pof->m_pbMemoryMappedStartAddress[0x5555]=0x90;
if(pof->m_pbMemoryMappedStartAddress[3]!=0) { // master lock bit is set, no erases or writes are going to happen
pof->m_fIsBelievedCapableOfWriteAndErase=false;
nPos+=sprintf(&pof->m_szFlashDescription[nPos], "Master Lock SET ");
}
// detect block lock situation
nPos+=sprintf(&pof->m_szFlashDescription[nPos], "Block Locks: ");
while(n<pof->m_dwLengthInBytes) {
pof->m_pbMemoryMappedStartAddress[0x5555]=0x90;
nPos+=sprintf(&pof->m_szFlashDescription[nPos], "%u", pof->m_pbMemoryMappedStartAddress[n|0x0002]&1);
n+=0x10000;
}
nPos+=sprintf(&pof->m_szFlashDescription[nPos], " ");
pof->m_pbMemoryMappedStartAddress[0x5555]=0x50;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xff;
}
}
pkft++;
}
}
if(!fSeen) {
if(
(baNormalModeFirstTwoBytes[0]==pof->m_bManufacturerId) &&
(baNormalModeFirstTwoBytes[1]==pof->m_pbMemoryMappedStartAddress[1])
) { // we didn't get anything worth reporting
sprintf(pof->m_szFlashDescription, "Read Only??? manf=0x%02X, dev=0x%02X", pof->m_bManufacturerId, pof->m_bDeviceId);
} else { // we got what is probably an unknown flash type
sprintf(pof->m_szFlashDescription, "manf=0x%02X, dev=0x%02X", pof->m_bManufacturerId, pof->m_bDeviceId);
}
}
return fSeen;
}
// uses the block erase function on the flash to erase the minimal footprint
// needed to cover pof->m_dwStartOffset .. (pof->m_dwStartOffset+pof->m_dwLengthUsedArea)
#define MAX_ERASE_RETRIES_IN_4KBLOCK_BEFORE_FAILING 4
bool BootFlashEraseMinimalRegion( OBJECT_FLASH *pof )
{
DWORD dw=pof->m_dwStartOffset;
DWORD dwLen=pof->m_dwLengthUsedArea;
DWORD dwLastEraseAddress=0xffffffff;
int nCountEraseRetryIn4KBlock=MAX_ERASE_RETRIES_IN_4KBLOCK_BEFORE_FAILING;
pof->m_szAdditionalErrorInfo[0]='\0';
if(pof->m_pcallbackFlash!=NULL)
if(!(pof->m_pcallbackFlash)(pof, EE_ERASE_START, 0, 0)) {
strcpy(pof->m_szAdditionalErrorInfo, "Erase Aborted");
return false;
}
while(dwLen) {
if(pof->m_pbMemoryMappedStartAddress[dw]!=0xff) { // something needs erasing
BYTE b;
if((dwLastEraseAddress & 0xfffff000)==(dw & 0xfffff000)) { // same 4K block?
nCountEraseRetryIn4KBlock--;
if(nCountEraseRetryIn4KBlock==0) { // run out of tries in this 4K block
if(pof->m_pcallbackFlash!=NULL) {
(pof->m_pcallbackFlash)(pof, EE_ERASE_ERROR, dw-pof->m_dwStartOffset, pof->m_pbMemoryMappedStartAddress[dw]);
(pof->m_pcallbackFlash)(pof, EE_ERASE_END, 0, 0);
}
sprintf(pof->m_szAdditionalErrorInfo, "Erase failed for block at +0x%x, reads as 0x%02X", dw, pof->m_pbMemoryMappedStartAddress[dw]);
return false; // failure
}
} else {
nCountEraseRetryIn4KBlock=MAX_ERASE_RETRIES_IN_4KBLOCK_BEFORE_FAILING; // different block, reset retry counter
dwLastEraseAddress=dw;
}
if(pof->m_fDetectedUsing28xxxConventions) {
int nCountMinSpin=0x100;
b=0x00;
pof->m_pbMemoryMappedStartAddress[0x5555]=0x50; // clear status register
// erase the block containing the non 0xff guy
pof->m_pbMemoryMappedStartAddress[dw]=0x20;
pof->m_pbMemoryMappedStartAddress[dw]=0xd0;
while((!(b&0x80)) || (nCountMinSpin)) { // busy - Sharp has a problem, does not go busy for ~500nS
b=pof->m_pbMemoryMappedStartAddress[dw];
if(nCountMinSpin) nCountMinSpin--;
}
pof->m_pbMemoryMappedStartAddress[0x5555]=0x50;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xff;
if(b&0x7e) { // uh-oh something wrong
if(pof->m_pcallbackFlash!=NULL) {
(pof->m_pcallbackFlash)(pof, EE_ERASE_ERROR, dw-pof->m_dwStartOffset, pof->m_pbMemoryMappedStartAddress[dw]);
(pof->m_pcallbackFlash)(pof, EE_ERASE_END, 0, 0);
}
if(b&8) {
sprintf(pof->m_szAdditionalErrorInfo, "This chip requires +5V on pin 11 (Vpp). See the README.");
} else {
sprintf(pof->m_szAdditionalErrorInfo, "Chip Status after Erase: 0x%02X", b);
}
return false;
}
} else { // more common 29xxx style
DWORD dwCountTries=0;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0x80;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[dw]=0x50; // erase the block containing the non 0xff guy
b=pof->m_pbMemoryMappedStartAddress[dw]; // waits until b6 is no longer toggling on each read
while((pof->m_pbMemoryMappedStartAddress[dw]&0x40)!=(b&0x40)) {
dwCountTries++; b^=0x40;
}
if(dwCountTries<3) { // <3 means never entered busy mode - block erase code 0x50 not supported, try alternate
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xf0;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0x80;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[dw]=0x30; // erase the block containing the non 0xff guy
b=pof->m_pbMemoryMappedStartAddress[dw];
dwCountTries=0;
while((pof->m_pbMemoryMappedStartAddress[dw]&0x40)!=(b&0x40)) {
dwCountTries++; b^=0x40;
}
}
// if we had a couple of unsuccessful tries at block erase already, try chip erase
// safety features...
if(
(dwCountTries<3) && // other commands did not work at all
(nCountEraseRetryIn4KBlock<2) && // had multiple attempts at them already
(pof->m_dwStartOffset==0) && // reprogramming whole chip .. starting from start
(pof->m_dwLengthUsedArea == pof->m_dwLengthInBytes) // and doing the whole length of the chip
) { // <3 means never entered busy mode - block erase code 0x30 not supported
#if 1
printk("Trying to erase whole chip\n");
#endif
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xf0;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0x80;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0x10; // chip erase ONLY available on W49F020
b=pof->m_pbMemoryMappedStartAddress[dw];
dwCountTries=0;
while((pof->m_pbMemoryMappedStartAddress[dw]&0x40)!=(b&0x40)) {
dwCountTries++; b^=0x40;
}
}
}
continue; // retry reading this address without moving on
}
// update callback every 1K addresses
if((dw&0x3ff)==0) {
if(pof->m_pcallbackFlash!=NULL) {
if(!(pof->m_pcallbackFlash)(pof, EE_ERASE_UPDATE, dw-pof->m_dwStartOffset, pof->m_dwLengthUsedArea)) {
strcpy(pof->m_szAdditionalErrorInfo, "Erase Aborted");
return false;
}
}
}
dwLen--; dw++;
}
if(pof->m_pcallbackFlash!=NULL) if(!(pof->m_pcallbackFlash)(pof, EE_ERASE_END, 0, 0)) return false;
return true;
}
// program the flash from the data in pba
// length of valid data in pba held in pof->m_dwLengthUsedArea
bool BootFlashProgram( OBJECT_FLASH *pof, BYTE *pba )
{
DWORD dw=pof->m_dwStartOffset;
DWORD dwLen=pof->m_dwLengthUsedArea;
DWORD dwSrc=0;
DWORD dwLastProgramAddress=0xffffffff;
int nCountProgramRetries=4;
pof->m_szAdditionalErrorInfo[0]='\0';
if(pof->m_pcallbackFlash!=NULL)
if(!(pof->m_pcallbackFlash)(pof, EE_PROGRAM_START, 0, 0)) {
strcpy(pof->m_szAdditionalErrorInfo, "Program Aborted");
return false;
}
// program
while(dwLen) {
if(pof->m_pbMemoryMappedStartAddress[dw]!=pba[dwSrc]) { // needs programming
if(dwLastProgramAddress==dw) {
nCountProgramRetries--;
if(nCountProgramRetries==0) {
if(pof->m_pcallbackFlash!=NULL) {
(pof->m_pcallbackFlash)(pof, EE_PROGRAM_ERROR, dw, (((DWORD)pba[dwSrc])<<8) |pof->m_pbMemoryMappedStartAddress[dw] );
(pof->m_pcallbackFlash)(pof, EE_PROGRAM_END, 0, 0);
}
sprintf(pof->m_szAdditionalErrorInfo, "Program failed for byte at +0x%x; wrote 0x%02X, read 0x%02X", dw, pba[dwSrc], pof->m_pbMemoryMappedStartAddress[dw]);
return false;
}
} else {
nCountProgramRetries=4;
dwLastProgramAddress=dw;
}
if(pof->m_fDetectedUsing28xxxConventions) {
BYTE b=0x0;
DWORD dwTimeToLive=0xfffff; // 1M times around, a few mS
int nCountMinSpin=2; // force wait for this long, suspect busy is not coming up immediately
pof->m_pbMemoryMappedStartAddress[dw]=0x40;
pof->m_pbMemoryMappedStartAddress[dw]=pba[dwSrc]; // perform programming action
while(((!(b&0x80)) && (--dwTimeToLive)) || (nCountMinSpin)) { // busy - Sharp has a problem, does not go busy for ~500nS
b=pof->m_pbMemoryMappedStartAddress[dw];
if(nCountMinSpin) nCountMinSpin--;
}
pof->m_pbMemoryMappedStartAddress[dw]=0x50;
pof->m_pbMemoryMappedStartAddress[dw]=0xff;
if((b&0x7e)||(!dwTimeToLive)) { // uh-oh something wrong
if(pof->m_pcallbackFlash!=NULL) {
(pof->m_pcallbackFlash)(pof, EE_PROGRAM_ERROR, dw-pof->m_dwStartOffset, (((DWORD)pba[dwSrc])<<8) | pof->m_pbMemoryMappedStartAddress[dw]);
(pof->m_pcallbackFlash)(pof, EE_PROGRAM_END, 0, 0);
}
if(dwTimeToLive) {
sprintf(pof->m_szAdditionalErrorInfo, "Chip Status after Program: 0x%02X", b);
} else {
sprintf(pof->m_szAdditionalErrorInfo, "Chip Status after TIMED-OUT Program: 0x%02X", b);
}
if(b&8) {
sprintf(pof->m_szAdditionalErrorInfo, "This chip requires +5V on pin 11 (Vpp). See the README.");
}
return false;
}
} else {
BYTE b;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xaa;
pof->m_pbMemoryMappedStartAddress[0x2aaa]=0x55;
pof->m_pbMemoryMappedStartAddress[0x5555]=0xa0;
pof->m_pbMemoryMappedStartAddress[dw]=pba[dwSrc]; // perform programming action
b=pof->m_pbMemoryMappedStartAddress[dw]; // waits until b6 is no longer toggling on each read
while((pof->m_pbMemoryMappedStartAddress[dw]&0x40)!=(b&0x40)) b^=0x40;
}
continue; // does NOT advance yet
}
if((dw&0x3ff)==0)
if(pof->m_pcallbackFlash!=NULL)
if(!(pof->m_pcallbackFlash)(pof, EE_PROGRAM_UPDATE, dwSrc, pof->m_dwLengthUsedArea)) {
strcpy(pof->m_szAdditionalErrorInfo, "Program Aborted");
return false;
}
dwLen--; dw++; dwSrc++;
}
if(pof->m_pcallbackFlash!=NULL) if(!(pof->m_pcallbackFlash)(pof, EE_PROGRAM_END, 0, 0)) return false;
// verify
if(pof->m_pcallbackFlash!=NULL) if(!(pof->m_pcallbackFlash)(pof, EE_VERIFY_START, 0, 0)) return false;
dw=pof->m_dwStartOffset;
dwLen=pof->m_dwLengthUsedArea;
dwSrc=0;
while(dwLen) {
if(pof->m_pbMemoryMappedStartAddress[dw]!=pba[dwSrc]) { // verify error
if(pof->m_pcallbackFlash!=NULL) if(!(pof->m_pcallbackFlash)(pof, EE_VERIFY_ERROR, dw, (((DWORD)pba[dwSrc])<<8) |pof->m_pbMemoryMappedStartAddress[dw])) return false;
if(pof->m_pcallbackFlash!=NULL) if(!(pof->m_pcallbackFlash)(pof, EE_VERIFY_END, 0, 0)) return false;
return false;
}
dwLen--; dw++; dwSrc++;
}
if(pof->m_pcallbackFlash!=NULL) if(!(pof->m_pcallbackFlash)(pof, EE_VERIFY_END, 0, 0)) return false;
return true;
}

View file

@ -1,65 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* 2003-01-06 andy@warmcat.com Created
*/
// header for BootFlash.c
// callback events
// note that if you receive *_START, you will always receive *_END even if an error is detected
typedef enum {
EE_ERASE_START=1,
EE_ERASE_UPDATE, // dwPos runs from 0 to dwExtent-1
EE_ERASE_END,
EE_ERASE_ERROR, // dwPos indicates error offset from start of flash
EE_PROGRAM_START,
EE_PROGRAM_UPDATE, // dwPos runs from 0 to dwExtent-1
EE_PROGRAM_END,
EE_PROGRAM_ERROR, // dwPos indicates error offset from start of flash, b7..b0 = read data, b15..b8 = written data
EE_VERIFY_START,
EE_VERIFY_UPDATE, // dwPos runs from 0 to dwExtent-1
EE_VERIFY_END,
EE_VERIFY_ERROR // dwPos indicates error offset from start of flash, b7..b0 = read data, b15..b8 = written data
} ENUM_EVENTS;
// callback typedef
typedef bool (*CALLBACK_FLASH)(void * pvoidObjectFlash, ENUM_EVENTS ee, DWORD dwPos, DWORD dwExtent);
typedef struct {
volatile BYTE * volatile m_pbMemoryMappedStartAddress; // fill on entry
BYTE m_bManufacturerId;
BYTE m_bDeviceId;
char m_szFlashDescription[256];
char m_szAdditionalErrorInfo[256];
DWORD m_dwLengthInBytes;
DWORD m_dwStartOffset;
DWORD m_dwLengthUsedArea;
CALLBACK_FLASH m_pcallbackFlash;
bool m_fDetectedUsing28xxxConventions;
bool m_fIsBelievedCapableOfWriteAndErase;
} OBJECT_FLASH;
typedef struct {
BYTE m_bManufacturerId;
BYTE m_bDeviceId;
char m_szFlashDescription[32];
DWORD m_dwLengthInBytes;
} KNOWN_FLASH_TYPE;
// requires pof->m_pbMemoryMappedStartAddress set to start address of flash in memory on entry
int BootReflashAndReset(BYTE *pbNewData, DWORD dwStartOffset, DWORD dwLength);
void BootReflashAndReset_RAM(BYTE *pbNewData, DWORD dwStartOffset, DWORD dwLength);
bool BootFlashGetDescriptor( OBJECT_FLASH *pof, KNOWN_FLASH_TYPE * pkft );
bool BootFlashEraseMinimalRegion( OBJECT_FLASH *pof);
bool BootFlashProgram( OBJECT_FLASH *pof, BYTE *pba );

View file

@ -1,115 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* 2003-01-07 andy@warmcat.com Created
*/
#include "boot.h"
#include "BootFlash.h"
#include "memory_layout.h"
void DisplayFlashProgressBar(int, int, unsigned long);
const KNOWN_FLASH_TYPE aknownflashtypesDefault[] = {
{ 0x01, 0xa4, "AMD - Am29F040B",0x80000 },
{ 0x01, 0xd5, "AMD - Am29F080B",0x100000 },
{ 0x01, 0xda, "AMD - Am29LV800B",0x100000 },
{ 0x04, 0xd5, "Fujitsu - MBM29F080A",0x100000 },
{ 0xad, 0xb0, "Hynix - HY29F002TT-90",0x40000 },
{ 0xad, 0xd5, "Hynix - HY29F080",0x100000 },
{ 0xc2, 0x36, "Macronix - MX29F022NTPC",0x40000 },
{ 0x20, 0xb0, "ST - M29F002BT",0x40000 },
{ 0x20, 0xf1, "ST - M29F080A",0x100000 },
{ 0xbf, 0x61, "SST SST49LF020",0x40000 },
{ 0x89, 0xa6, "Sharp LHF08CH1",0x100000 },
{ 0xda, 0x8c, "Winbond W49F020",0x40000 },
{ 0xda, 0x0b, "Winbond - W49F002U",0x40000 },
{ 0, 0, "", 0 } // terminator
};
// callback to show progress
bool BootFlashUserInterface(void * pvoidObjectFlash, ENUM_EVENTS ee, DWORD dwPos, DWORD dwExtent) {
if(ee==EE_ERASE_UPDATE){
DisplayFlashProgressBar(dwPos,dwExtent,0xffffff00);
}
else if(ee==EE_PROGRAM_UPDATE){
DisplayFlashProgressBar(dwPos,dwExtent,0xff00ff00);
}
return true;
}
void DisplayFlashProgressBar(int currentVal, int maxVal, unsigned long color) {
int x,y,l,w,h,m;
DWORD *fb=(DWORD*)FB_START;
if(maxVal<2){
return;
}
w=vmode.height;
h=vmode.width;
l=w-100;
y=h-100;
m=((w-150)>>2)*currentVal/maxVal;
m*=4;
m+=50;
for(x=50;x<l;x++){
fb[y*w+x]=0xffffffff;
fb[(y+1)*w+x]=0xffffffff;
if(x>55 && x<m){
int z;
for(z=5;z<45;z++){
fb[(y+z)*w+x]=color;
}
}
fb[(y+50)*w+x]=0xffffffff;
fb[(y+51)*w+x]=0xffffffff;
}
for(;y<h-50;y++){
fb[y*w+51]=0xffffffff;
fb[y*w+50]=0xffffffff;
fb[y*w+l-1]=0xffffffff;
fb[y*w+l-2]=0xffffffff;
}
}
// if things go well, we won't be coming back from this
// note this is copied to RAM, and the flash will be changed during its operation
// therefore no library code nor interrupts can be had
int BootReflashAndReset(BYTE *pbNewData, DWORD dwStartOffset, DWORD dwLength)
{
OBJECT_FLASH of;
bool fMore=true;
// prep our flash object with start address and params
of.m_pbMemoryMappedStartAddress=(BYTE *)LPCFlashadress;
of.m_dwStartOffset=dwStartOffset;
of.m_dwLengthUsedArea=dwLength;
of.m_pcallbackFlash=BootFlashUserInterface;
// check device type and parameters are sane
if(!BootFlashGetDescriptor(&of, (KNOWN_FLASH_TYPE *)&aknownflashtypesDefault[0])) return 1; // unable to ID device - fail
if(!of.m_fIsBelievedCapableOfWriteAndErase) return 2; // seems to be write-protected - fail
if(of.m_dwLengthInBytes<(dwStartOffset+dwLength)) return 3; // requested layout won't fit device - sanity check fail
// committed to reflash now
while(fMore) {
if(BootFlashEraseMinimalRegion(&of)) {
if(BootFlashProgram(&of, pbNewData)) {
fMore=false; // good situation
} else { // failed program
;
}
} else { // failed erase
;
}
}
return 0; // keep compiler happy
}

View file

@ -1,4 +0,0 @@
O_TARGET := BootFlash.o BootFlashUi.o
include $(TOPDIR)/Rules.make

View file

@ -1,224 +0,0 @@
#include "boot.h"
#include "sha1.h"
#include "rc4.h"
#include <stdarg.h>
//#include <string.h>
void HMAC_hdd_calculation(int version,unsigned char *HMAC_result, ... );
extern size_t strlen(const char * s);
int copy_swap_trim(unsigned char *dst, unsigned char *src, int len)
{
unsigned char tmp;
int i;
for (i=0; i < len; i+=2) {
tmp = src[i]; //allow swap in place
dst[i] = src[i+1];
dst[i+1] = tmp;
}
--dst;
for (i=len; i>0; --i) {
if (dst[i] != ' ') {
dst[i+1] = 0;
break;
}
}
return i;
}
int HMAC1hddReset(int version,SHA1Context *context)
{
SHA1Reset(context);
switch (version) {
case 9:
context->Intermediate_Hash[0] = 0x85F9E51A;
context->Intermediate_Hash[1] = 0xE04613D2;
context->Intermediate_Hash[2] = 0x6D86A50C;
context->Intermediate_Hash[3] = 0x77C32E3C;
context->Intermediate_Hash[4] = 0x4BD717A4;
break;
case 10:
context->Intermediate_Hash[0] = 0x72127625;
context->Intermediate_Hash[1] = 0x336472B9;
context->Intermediate_Hash[2] = 0xBE609BEA;
context->Intermediate_Hash[3] = 0xF55E226B;
context->Intermediate_Hash[4] = 0x99958DAC;
break;
case 11:
context->Intermediate_Hash[0] = 0x39B06E79;
context->Intermediate_Hash[1] = 0xC9BD25E8;
context->Intermediate_Hash[2] = 0xDBC6B498;
context->Intermediate_Hash[3] = 0x40B4389D;
context->Intermediate_Hash[4] = 0x86BBD7ED;
break;
case 12:
context->Intermediate_Hash[0] = 0x8058763a;
context->Intermediate_Hash[1] = 0xf97d4e0e;
context->Intermediate_Hash[2] = 0x865a9762;
context->Intermediate_Hash[3] = 0x8a3d920d;
context->Intermediate_Hash[4] = 0x08995b2c;
break;
}
context->Length_Low = 512;
return shaSuccess;
}
int HMAC2hddReset(int version,SHA1Context *context)
{
SHA1Reset(context);
switch (version) {
case 9:
context->Intermediate_Hash[0] = 0x5D7A9C6B;
context->Intermediate_Hash[1] = 0xE1922BEB;
context->Intermediate_Hash[2] = 0xB82CCDBC;
context->Intermediate_Hash[3] = 0x3137AB34;
context->Intermediate_Hash[4] = 0x486B52B3;
break;
case 10:
context->Intermediate_Hash[0] = 0x76441D41;
context->Intermediate_Hash[1] = 0x4DE82659;
context->Intermediate_Hash[2] = 0x2E8EF85E;
context->Intermediate_Hash[3] = 0xB256FACA;
context->Intermediate_Hash[4] = 0xC4FE2DE8;
break;
case 11:
context->Intermediate_Hash[0] = 0x9B49BED3;
context->Intermediate_Hash[1] = 0x84B430FC;
context->Intermediate_Hash[2] = 0x6B8749CD;
context->Intermediate_Hash[3] = 0xEBFE5FE5;
context->Intermediate_Hash[4] = 0xD96E7393;
break;
case 12:
context->Intermediate_Hash[0] = 0x01075307;
context->Intermediate_Hash[1] = 0xa2f1e037;
context->Intermediate_Hash[2] = 0x1186eeea;
context->Intermediate_Hash[3] = 0x88da9992;
context->Intermediate_Hash[4] = 0x168a5609;
break;
}
context->Length_Low = 512;
return shaSuccess;
}
void HMAC_SHA1( unsigned char *result,
unsigned char *key, int key_length,
unsigned char *text1, int text1_length,
unsigned char *text2, int text2_length )
{
unsigned char state1[0x40];
unsigned char state2[0x40+0x14];
int i;
struct SHA1Context context;
for(i=0x40-1; i>=key_length;--i) state1[i] = 0x36;
for(;i>=0;--i) state1[i] = key[i] ^ 0x36;
SHA1Reset(&context);
SHA1Input(&context,state1,0x40);
SHA1Input(&context,text1,text1_length);
SHA1Input(&context,text2,text2_length);
SHA1Result(&context,&state2[0x40]);
for(i=0x40-1; i>=key_length;--i) state2[i] = 0x5C;
for(;i>=0;--i) state2[i] = key[i] ^ 0x5C;
SHA1Reset(&context);
SHA1Input(&context,state2,0x40+0x14);
SHA1Result(&context,result);
}
void HMAC_hdd_calculation(int version,unsigned char *HMAC_result, ... )
{
va_list args;
struct SHA1Context context;
va_start(args,HMAC_result);
HMAC1hddReset(version, &context);
while(1) {
unsigned char *buffer = va_arg(args,unsigned char *);
int length;
if (buffer == NULL) break;
length = va_arg(args,int);
SHA1Input(&context,buffer,length);
}
va_end(args);
SHA1Result(&context,&context.Message_Block[0]);
HMAC2hddReset(version, &context);
SHA1Input(&context,&context.Message_Block[0],0x14);
SHA1Result(&context,HMAC_result);
}
DWORD BootHddKeyGenerateEepromKeyData(
BYTE *pbEeprom_data,
BYTE *pbResult
) {
BYTE baKeyHash[20];
BYTE baDataHashConfirm[20];
BYTE baEepromDataLocalCopy[0x30];
struct rc4_key RC4_key;
int version = 0;
int counter;
int n,f;
// Static Version change not included yet
for (counter=9;counter<13;counter++)
{
memset(&RC4_key,0,sizeof(rc4_key));
memcpy(&baEepromDataLocalCopy[0], pbEeprom_data, 0x30);
// Calculate the Key-Hash
HMAC_hdd_calculation(counter, baKeyHash, &baEepromDataLocalCopy[0], 20, NULL);
//initialize RC4 key
rc4_prepare_key(baKeyHash, 20, &RC4_key);
//decrypt data (from eeprom) with generated key
rc4_crypt(&baEepromDataLocalCopy[20],8,&RC4_key); //confounder of some kind?
rc4_crypt(&baEepromDataLocalCopy[28],20,&RC4_key); //"real" data
// Calculate the Confirm-Hash
HMAC_hdd_calculation(counter, baDataHashConfirm, &baEepromDataLocalCopy[20], 8, &baEepromDataLocalCopy[28], 20, NULL);
f=0;
for(n=0;n<0x14;n++) {
if(baEepromDataLocalCopy[n]!=baDataHashConfirm[n]) f=1;
}
if (f==0) {
// Confirm Hash is correct
// Copy actual Xbox Version to Return Value
version=counter;
// exits the loop
break;
}
}
//copy out HDKey
memcpy(pbResult,&baEepromDataLocalCopy[28],16);
return version;
}

File diff suppressed because it is too large Load diff

View file

@ -1,9 +0,0 @@
/* Cromwell IDE driver code - GNU GPL */
#include "boot.h"
tsHarddiskInfo tsaHarddiskInfo[2]; // static struct stores data about attached drives
//Methods
int BootIdeInit(void);
int BootIdeReadSector(int nDriveIndex, void * pbBuffer, unsigned int block, int byte_offset, int n_bytes) ;
int BootIdeReadData(unsigned uIoBase, void * buf, size_t size);

View file

@ -1,5 +0,0 @@
EXTRA_CFLAGS := -I$(TOPDIR)/fs/grub -I$(TOPDIR)/lib/crypt
O_TARGET := BootIde.o BootHddKey.o
include $(TOPDIR)/Rules.make

View file

@ -1,510 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
*/
#include "boot.h"
#include "config.h"
#include "cpu.h"
volatile int nCountI2cinterrupts, nCountUnusedInterrupts, nCountUnusedInterruptsPic2, nCountInterruptsSmc, nCountInterruptsIde;
volatile bool fSeenPowerdown;
volatile TRAY_STATE traystate;
unsigned int wait_ms_time;
volatile int nInteruptable = 0;
// interrupt service stubs defined in BootStartup.S
extern void IntHandlerTimer0(void);
extern void IntHandlerI2C(void);
extern void IntHandlerSmc(void);
extern void IntHandlerIde(void);
extern void IntHandlerUnused(void);
extern void IntHandlerUnusedPic2(void);
extern void IntHandler1(void);
extern void IntHandler2(void);
extern void IntHandler3(void);
extern void IntHandler4(void);
extern void IntHandler5(void);
extern void IntHandler6(void);
extern void IntHandler7(void);
extern void IntHandler8(void);
extern void IntHandler9(void);
extern void IntHandler10(void);
extern void IntHandler13(void);
extern void IntHandler15(void);
extern void IntHandlerException0(void);
extern void IntHandlerException1(void);
extern void IntHandlerException2(void);
extern void IntHandlerException3(void);
extern void IntHandlerException4(void);
extern void IntHandlerException5(void);
extern void IntHandlerException6(void);
extern void IntHandlerException7(void);
extern void IntHandlerException8(void);
extern void IntHandlerException9(void);
extern void IntHandlerExceptionA(void);
extern void IntHandlerExceptionB(void);
extern void IntHandlerExceptionC(void);
extern void IntHandlerExceptionD(void);
extern void IntHandlerExceptionE(void);
extern void IntHandlerExceptionF(void);
extern void IntHandlerException10(void);
// structure defining our ISRs
typedef struct {
BYTE m_bInterruptCpu;
DWORD m_dwpVector;
} ISR_PREP;
const ISR_PREP isrprep[] = {
{ 0x00, (DWORD)IntHandlerException0 },
{ 0x01, (DWORD)IntHandlerException1 },
{ 0x02, (DWORD)IntHandlerException2 },
{ 0x03, (DWORD)IntHandlerException3 },
{ 0x04, (DWORD)IntHandlerException4 },
{ 0x05, (DWORD)IntHandlerException5 },
{ 0x06, (DWORD)IntHandlerException6 },
{ 0x07, (DWORD)IntHandlerException7 },
{ 0x08, (DWORD)IntHandlerException8 },
{ 0x09, (DWORD)IntHandlerException9 },
{ 0x0a, (DWORD)IntHandlerExceptionA },
{ 0x0b, (DWORD)IntHandlerExceptionB },
{ 0x0c, (DWORD)IntHandlerExceptionC },
{ 0x0d, (DWORD)IntHandlerExceptionD },
{ 0x0e, (DWORD)IntHandlerExceptionE },
{ 0x0f, (DWORD)IntHandlerExceptionF },
{ 0x10, (DWORD)IntHandlerException10 },
// interrupts from PIC1
{ 0x20, (DWORD)IntHandlerTimer0 },
{ 0x21, (DWORD)IntHandler1 },
{ 0x22, (DWORD)IntHandler2 },
{ 0x23, (DWORD)IntHandler3 },
{ 0x24, (DWORD)IntHandler4 },
{ 0x25, (DWORD)IntHandler5 },
{ 0x26, (DWORD)IntHandler6 },
{ 0x27, (DWORD)IntHandler7 },
// interrupts from PIC 2
{ 0x70, (DWORD)IntHandler8 },
{ 0x71, (DWORD)IntHandler9 },
{ 0x72, (DWORD)IntHandler10 },
{ 0x73, (DWORD)IntHandlerI2C },
{ 0x74, (DWORD)IntHandlerSmc },
{ 0x75, (DWORD)IntHandler13 },
{ 0x76, (DWORD)IntHandlerIde },
{ 0x77, (DWORD)IntHandler15 },
{ 0, 0 }
};
void wait_smalldelay(void) {
wait_us(80);
}
void wait_us(DWORD ticks) {
/*
32 Bit range = 1200 sec ! => 20 min
1. sec = 0x369E99
1 ms = 3579,545
*/
DWORD COUNT_start;
DWORD temp;
DWORD COUNT_TO;
DWORD HH;
// Maximum Input range
if (ticks>(1200*1000)) ticks = 1200*1000;
COUNT_TO = (DWORD) ((float)(ticks*3.579545));
COUNT_start = IoInputDword(0x8008);
while(1) {
// Reads out the System timer
HH = IoInputDword(0x8008);
temp = HH-COUNT_start;
// We reached the counter
if (temp>COUNT_TO) break;
};
}
void wait_ms(DWORD ticks) {
/*
32 Bit range = 1200 sec ! => 20 min
1. sec = 0x369E99
1 ms = 3579,545
*/
DWORD COUNT_start;
DWORD temp;
DWORD COUNT_TO;
DWORD HH;
// Maximum Input range
if (ticks>(1200*1000)) ticks = 1200*1000;
COUNT_TO = (DWORD) ((float)(ticks*3579.545));
COUNT_start = IoInputDword(0x8008);
while(1) {
// Reads out the System timer
HH = IoInputDword(0x8008);
temp = HH-COUNT_start;
// We reached the counter
if (temp>COUNT_TO) break;
};
}
void BootInterruptsWriteIdt() {
volatile ts_pm_interrupt * ptspmi=(volatile ts_pm_interrupt *)(0xb0000); // ie, start of IDT area
int n, n1=0;
// init storage used by ISRs
VIDEO_VSYNC_POSITION=0;
BIOS_TICK_COUNT=0;
VIDEO_VSYNC_DIR=0;
nCountI2cinterrupts=0;
nCountUnusedInterrupts=0;
nCountUnusedInterruptsPic2=0;
nCountInterruptsSmc=0;
nCountInterruptsIde=0;
fSeenPowerdown=false;
traystate=ETS_OPEN_OR_OPENING;
VIDEO_LUMASCALING=0;
VIDEO_RSCALING=0;
VIDEO_BSCALING=0;
// set up default exception, interrupt vectors to dummy stubs
for(n=0;n<0x100;n++) { // have to do 256
ptspmi[n].m_wSelector=0x10;
ptspmi[n].m_wType=0x8e00; // interrupt gate, 32-bit
if(n==isrprep[n1].m_bInterruptCpu) { // is it next on our prep list? If so, stick it in
ptspmi[n].m_wHandlerHighAddressLow16=(WORD)isrprep[n1].m_dwpVector;
ptspmi[n].m_wHandlerLinearAddressHigh16=(WORD)(((DWORD)isrprep[n1].m_dwpVector)>>16);
n1++;
} else { // otherwise default handler (pretty useless, but will catch it)
ptspmi[n].m_wHandlerHighAddressLow16=(WORD)IntHandlerUnused;
ptspmi[n].m_wHandlerLinearAddressHigh16=(WORD)(((DWORD)IntHandlerUnused)>>16);
}
}
// set up the Programmable Inetrrupt Controllers
IoOutputByte(0x20, 0x15); // master PIC setup
IoOutputByte(0x21, 0x20); // base interrupt vector address
IoOutputByte(0x21, 0x04); // am master, INT2 is hooked to slave
IoOutputByte(0x21, 0x01); // x86 mode, normal EOI
IoOutputByte(0x21, 0x00); // enable all ints
IoOutputByte(0xa0, 0x15); // slave PIC setup
IoOutputByte(0xa1, 0x70); // base interrupt vector address
IoOutputByte(0xa1, 0x02); // am slave, hooked to INT2 on master
IoOutputByte(0xa1, 0x01); // x86 mode normal EOI
if (cromwell_config==XROMWELL) IoOutputByte(0xa1, 0xaf); // enable int14(IDE) int12(SMI)
if (cromwell_config==CROMWELL) IoOutputByte(0xa1, 0x00);
// enable interrupts
intel_interrupts_on();
}
///////////////////////////////////////////
//
// ISRs
void IntHandlerCSmc(void)
{
BYTE bStatus, nBit=0;
unsigned int temp;
BYTE temp_AV_mode;
nCountInterruptsSmc++;
temp = IoInputWord(0x8000);
if (temp!=0x0) {
IoOutputWord(0x8000,temp);
//printk("System Timer wants to sleep we kill him");
// return;
}
bStatus=I2CTransmitByteGetReturn(0x10, 0x11); // Query PIC for interrupt reason
// we do nothing, if there is not Interrupt reason
if (bStatus==0x0) return;
while(nBit<7) {
if(bStatus & 1) {
BYTE b=0x04;
switch(nBit) {
case 0: // POWERDOWN EVENT
bprintf("SMC Interrupt %d: Powerdown\n", nCountInterruptsSmc);
I2CTransmitWord(0x10, 0x0200);
I2CTransmitWord(0x10, 0x0100|b);
I2CTransmitWord(0x10, 0x0500|b);
I2CTransmitWord(0x10, 0x0600|b);
I2CTransmitWord(0x10, 0x0900|b);
I2CTransmitWord(0x10, 0x0a00|b);
I2CTransmitWord(0x10, 0x0b00|b);
I2CTransmitWord(0x10, 0x0d00|b);
I2CTransmitWord(0x10, 0x0e00|b);
I2CTransmitWord(0x10, 0x0f00|b);
I2CTransmitWord(0x10, 0x1000|b);
I2CTransmitWord(0x10, 0x1200|b);
I2CTransmitWord(0x10, 0x1300|b);
I2CTransmitWord(0x10, 0x1400|b);
I2CTransmitWord(0x10, 0x1500|b);
I2CTransmitWord(0x10, 0x1600|b);
I2CTransmitWord(0x10, 0x1700|b);
I2CTransmitWord(0x10, 0x1800|b);
fSeenPowerdown=true;
/*
// sequence in 2bl at halt_it
IoOutputDword(0xcf8, 0x8000036C); // causes weird double-height video, jittery, like it screwed with clock
IoOutputDword(0xcfc, 0x1000000);
__asm__ __volatile__("hlt" );
*/
break;
case 1: // CDROM TRAY IS NOW CLOSED
traystate=ETS_CLOSED;
bprintf("SMC Interrupt %d: CDROM Tray now Closed\n", nCountInterruptsSmc);
DVD_TRAY_STATE = DVD_CLOSED;
break;
case 2: // CDROM TRAY IS STARTING OPENING
traystate=ETS_OPEN_OR_OPENING;
DVD_TRAY_STATE = DVD_OPENING;
I2CTransmitWord(0x10, 0x0d02);
bprintf("SMC Interrupt %d: CDROM starting opening\n", nCountInterruptsSmc);
break;
case 3: // AV CABLE HAS BEEN PLUGGED IN
temp_AV_mode =I2CTransmitByteGetReturn(0x10, 0x04);
// Compare to global variable
if (VIDEO_AV_MODE != temp_AV_mode ) {
VIDEO_AV_MODE = 0xff;
wait_ms(30);
VIDEO_AV_MODE = temp_AV_mode;
BootVgaInitializationKernelNG((CURRENT_VIDEO_MODE_DETAILS *)&vmode);
wait_ms(200);
BootVgaInitializationKernelNG((CURRENT_VIDEO_MODE_DETAILS *)&vmode);
}
break;
case 4: // AV CABLE HAS BEEN UNPLUGGED
bprintf("SMC Interrupt %d: AV cable unplugged\n", nCountInterruptsSmc);
VIDEO_AV_MODE=0xff;
//vmode.m_bAvPack=0xff;
break;
case 5: // BUTTON PRESSED REQUESTING TRAY OPEN
traystate=ETS_OPEN_OR_OPENING;
I2CTransmitWord(0x10, 0x0d04);
I2CTransmitWord(0x10, 0x0c00);
bprintf("SMC Interrupt %d: CDROM tray opening by Button press\n", nCountInterruptsSmc);
bStatus&=~0x02; // kill possibility of conflicting closing report
break;
case 6: // CDROM TRAY IS STARTING CLOSING
traystate=ETS_CLOSING;
DVD_TRAY_STATE = DVD_CLOSING;
bprintf("SMC Interrupt %d: CDROM tray starting closing\n", nCountInterruptsSmc);
break;
case 7: // UNKNOWN
bprintf("SMC Interrupt %d: b7 Reason code\n", nCountInterruptsSmc);
break;
}
}
nBit++;
bStatus>>=1;
}
}
void IntHandlerCIde(void)
{
if(!nInteruptable) return;
IoInputByte(0x1f7);
bprintf("IDE Interrupt\n");
nCountInterruptsIde++;
}
void IntHandlerCI2C(void)
{
if(!nInteruptable) return;
nCountI2cinterrupts++;
}
void IntHandlerUnusedC(void)
{
if(!nInteruptable) return;
bprintf("Unhandled Interrupt\n");
//printk("Unhandled Interrupt");
nCountUnusedInterrupts++;
//while(1) ;
}
void IntHandlerUnusedC2(void)
{
if(!nInteruptable) return;
bprintf("Unhandled Interrupt 2\n");
nCountUnusedInterruptsPic2++;
}
// this guy is getting called at 18.2Hz
void IntHandlerCTimer0(void)
{
#ifdef DEBUG_MODE
extern volatile ohci_t usbcontroller[2];
#endif
BIOS_TICK_COUNT++;
#ifdef DEBUG_MODE
if(!nInteruptable) return;
#endif
}
// USB interrupt
void IntHandler1C(void)
{
// Interrupt for OHCI controller located on 0xfed00000
}
void IntHandler9C(void)
{
// Interrupt for OHCI controller located on 0xfed08000
}
void IntHandler2C(void)
{
if(!nInteruptable) return;
bprintf("Interrupt 2\n");
}
void IntHandler3VsyncC(void) // video VSYNC
{
*((volatile DWORD *)0xfd600100)=0x1; // clear VSYNC int
}
void IntHandler4C(void)
{
if(!nInteruptable) return;
bprintf("Interrupt 4\n");
}
void IntHandler5C(void)
{
if(!nInteruptable) return;
bprintf("Interrupt 5\n");
}
void IntHandler6C(void) {
bprintf("Interrupt 6\n");
}
void IntHandler7C(void)
{
if(!nInteruptable) return;
bprintf("Interrupt 7\n");
}
void IntHandler8C(void)
{
bprintf("Interrupt 8\n");
}
void IntHandler10C(void)
{
if(!nInteruptable) return;
bprintf("Interrupt 10\n");
}
void IntHandler13C(void)
{
bprintf("Interrupt 13\n");
}
void IntHandler15C(void)
{
if(!nInteruptable) return;
bprintf("Unhandled Interrupt 15\n");
}
//void IntHandlerException0C(void) { bprintf("CPU Exc: Divide by Zero\n"); while(1) ; }
void IntHandlerException0C(void) { bprintf("CPU Exc: Divide by Zero\n");}
void IntHandlerException1C(void) { bprintf("CPU Exc: Single Step\n"); while(1) ; }
void IntHandlerException2C(void) { bprintf("CPU Exc: NMI\n"); while(1) ; }
void IntHandlerException3C(void) { bprintf("CPU Exc: Breakpoint\n"); while(1) ; }
void IntHandlerException4C(void) { bprintf("CPU Exc: Overflow Trap\n"); while(1) ; }
void IntHandlerException5C(void) { bprintf("CPU Exc: BOUND exceeded\n"); while(1) ; }
void IntHandlerException6C(void) {
DWORD dwEbp=0;
bprintf("CPU Exc: Invalid Opcode\n");
__asm__ __volatile__ ( " mov %%esp, %%eax\n " : "=a" (dwEbp) );
bprintf(" %08lX:%08lX\n", *((volatile DWORD *)(dwEbp+0x48)), *((volatile DWORD *)(dwEbp+0x44)));
while(1) ;
}
//void IntHandlerException7C(void) { bprintf("CPU Exc: Coprocessor Absent\n"); while(1) ; }
void IntHandlerException7C(void) { bprintf("CPU Exc: Coprocessor Absent\n");}
void IntHandlerException8C(void) { bprintf("CPU Exc: Double Fault\n"); while(1) ; }
//void IntHandlerException9C(void) { bprintf("CPU Exc: Copro Seg Overrun\n"); while(1) ; }
void IntHandlerException9C(void) { bprintf("CPU Exc: Copro Seg Overrun\n");}
void IntHandlerExceptionAC(void) { bprintf("CPU Exc: Invalid TSS\n"); while(1) ; }
void IntHandlerExceptionBC(void) { bprintf("CPU Exc: Segment not present\n"); while(1) ; }
void IntHandlerExceptionCC(void) { bprintf("CPU Exc: Stack Exception\n"); while(1) ; }
void IntHandlerExceptionDC(void) { bprintf("CPU Exc: General Protection Fault\n"); while(1) ; }
void IntHandlerExceptionEC(void) { bprintf("CPU Exc: Page Fault\n"); while(1) ; }
void IntHandlerExceptionFC(void) { bprintf("CPU Exc: Reserved\n"); while(1) ; }
//void IntHandlerException10C(void) { bprintf("CPU Exc: Copro Error\n"); while(1) ; }
void IntHandlerException10C(void) { bprintf("CPU Exc: Copro Error\n");}

View file

@ -1,5 +0,0 @@
EXTRA_CFLAGS := -I$(TOPDIR)/drivers/cpu
O_TARGET := BootInterrupts.o pci.o i2cio.o
include $(TOPDIR)/Rules.make

View file

@ -1,226 +0,0 @@
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "boot.h"
/*
WriteToSMBus() by Lehner Franz (franz@caos.at)
ReadfromSMBus() by Lehner Franz (franz@caos.at)
*/
int WriteToSMBus(BYTE Address,BYTE bRegister,BYTE Size,DWORD Data_to_smbus)
{
int nRetriesToLive=50;
while(IoInputWord(I2C_IO_BASE+0)&0x0800) ; // Franz's spin while bus busy with any master traffic
while(nRetriesToLive--) {
BYTE b;
unsigned int temp;
IoOutputByte(I2C_IO_BASE+4, (Address<<1)|0);
IoOutputByte(I2C_IO_BASE+8, bRegister);
switch (Size) {
case 4:
/*
IoOutputByte(I2C_IO_BASE+9, Data_to_smbus&0xff);
IoOutputByte(I2C_IO_BASE+9, (Data_to_smbus >> 8) & 0xff );
IoOutputByte(I2C_IO_BASE+9, (Data_to_smbus >> 16) & 0xff );
IoOutputByte(I2C_IO_BASE+9, (Data_to_smbus >> 24) & 0xff );
*/
// Reversed
IoOutputByte(I2C_IO_BASE+9, (Data_to_smbus >> 24) & 0xff );
IoOutputByte(I2C_IO_BASE+9, (Data_to_smbus >> 16) & 0xff );
IoOutputByte(I2C_IO_BASE+9, (Data_to_smbus >> 8) & 0xff );
IoOutputByte(I2C_IO_BASE+9, Data_to_smbus&0xff);
IoOutputWord(I2C_IO_BASE+6, 4);
break;
case 2:
IoOutputWord(I2C_IO_BASE+6, Data_to_smbus&0xffff);
break;
default: // 1
IoOutputWord(I2C_IO_BASE+6, Data_to_smbus&0xff);
break;
}
temp = IoInputWord(I2C_IO_BASE+0);
IoOutputWord(I2C_IO_BASE+0, temp); // clear down all preexisting errors
switch (Size) {
case 4:
IoOutputByte(I2C_IO_BASE+2, 0x1d); // DWORD modus
break;
case 2:
IoOutputByte(I2C_IO_BASE+2, 0x1b); // WORD modus
break;
default: // 1
IoOutputByte(I2C_IO_BASE+2, 0x1a); // BYTE modus
break;
}
b = 0;
while( (b&0x36)==0 ) { b=IoInputByte(I2C_IO_BASE+0); }
if ((b&0x10) != 0) {
return ERR_SUCCESS;
}
wait_us(1);
}
return ERR_I2C_ERROR_BUS;
}
int ReadfromSMBus(BYTE Address,BYTE bRegister,BYTE Size,DWORD *Data_to_smbus)
{
int nRetriesToLive=50;
while(IoInputWord(I2C_IO_BASE+0)&0x0800) ; // Franz's spin while bus busy with any master traffic
while(nRetriesToLive--) {
BYTE b;
int temp;
IoOutputByte(I2C_IO_BASE+4, (Address<<1)|1);
IoOutputByte(I2C_IO_BASE+8, bRegister);
temp = IoInputWord(I2C_IO_BASE+0);
IoOutputWord(I2C_IO_BASE+0, temp); // clear down all preexisting errors
switch (Size) {
case 4:
IoOutputByte(I2C_IO_BASE+2, 0x0d); // DWORD modus ?
break;
case 2:
IoOutputByte(I2C_IO_BASE+2, 0x0b); // WORD modus
break;
default:
IoOutputByte(I2C_IO_BASE+2, 0x0a); // BYTE
break;
}
b = 0;
while( (b&0x36)==0 ) { b=IoInputByte(I2C_IO_BASE+0); }
if(b&0x24) {
//printf("I2CTransmitByteGetReturn error %x\n", b);
}
if(!(b&0x10)) {
//printf("I2CTransmitByteGetReturn no complete, retry\n");
} else {
switch (Size) {
case 4:
IoInputByte(I2C_IO_BASE+6);
IoInputByte(I2C_IO_BASE+9);
IoInputByte(I2C_IO_BASE+9);
IoInputByte(I2C_IO_BASE+9);
IoInputByte(I2C_IO_BASE+9);
break;
case 2:
*Data_to_smbus = IoInputWord(I2C_IO_BASE+6);
break;
default:
*Data_to_smbus = IoInputByte(I2C_IO_BASE+6);
break;
}
return ERR_SUCCESS;
}
}
return ERR_I2C_ERROR_BUS;
}
/* ************************************************************************************************************* */
int I2CWriteWordtoRegister(BYTE bPicAddressI2cFormat,BYTE bRegister ,WORD wDataToWrite)
{
// int WriteToSMBus(BYTE Address,BYTE bRegister,BYTE Size,DWORD Data_to_smbus)
return WriteToSMBus(bPicAddressI2cFormat,bRegister,2,wDataToWrite);
}
/* --------------------- Normal 8 bit operations -------------------------- */
int I2CTransmitByteGetReturn(BYTE bPicAddressI2cFormat, BYTE bDataToWrite)
{
unsigned int temp;
if (ReadfromSMBus(bPicAddressI2cFormat,bDataToWrite,1,&temp) != ERR_SUCCESS) return ERR_I2C_ERROR_BUS;
return temp;
}
// transmit a word, no returned data from I2C device
int I2CTransmitWord(BYTE bPicAddressI2cFormat, WORD wDataToWrite)
{
// int WriteToSMBus(BYTE Address,BYTE bRegister,BYTE Size,DWORD Data_to_smbus)
return WriteToSMBus(bPicAddressI2cFormat,(wDataToWrite>>8)&0xff,1,(wDataToWrite&0xff));
}
int I2CWriteBytetoRegister(BYTE bPicAddressI2cFormat, BYTE bRegister, BYTE wDataToWrite)
{
// int WriteToSMBus(BYTE Address,BYTE bRegister,BYTE Size,DWORD Data_to_smbus)
return WriteToSMBus(bPicAddressI2cFormat,bRegister,1,(wDataToWrite&0xff));
}
void I2CModifyBits(BYTE bAds, BYTE bReg, BYTE bData, BYTE bMask)
{
BYTE b=I2CTransmitByteGetReturn(0x45, bReg)&(~bMask);
I2CTransmitWord(0x45, (bReg<<8)|((bData)&bMask)|b);
}
// ---------------------------- PIC challenge/response -----------------------------------------------------------
extern int I2cSetFrontpanelLed(BYTE b)
{
I2CTransmitWord( 0x10, 0x800 | b); // sequencing thanks to Jarin the Penguin!
I2CTransmitWord( 0x10, 0x701);
return ERR_SUCCESS;
}
bool I2CGetTemperature(int * pnLocalTemp, int * pExternalTemp)
{
*pnLocalTemp=I2CTransmitByteGetReturn(0x4c, 0x01);
*pExternalTemp=I2CTransmitByteGetReturn(0x4c, 0x00);
//Check for bus error - 1.6 xboxes have no readable
//temperature sensors.
if (*pnLocalTemp==ERR_I2C_ERROR_BUS ||
*pExternalTemp==ERR_I2C_ERROR_BUS)
return false;
return true;
}

View file

@ -1,409 +0,0 @@
#include "boot.h"
// by ozpaulb@hotmail.com 2002-07-14
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
BYTE PciReadByte(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off)
{
DWORD base_addr = 0x80000000;
base_addr |= ((bus & 0xFF) << 16); // bus #
base_addr |= ((dev & 0x1F) << 11); // device #
base_addr |= ((func & 0x07) << 8); // func #
IoOutputDword(0xcf8, (base_addr + (reg_off & 0xfc)));
return IoInputByte(0xcfc + (reg_off & 3));
}
void PciWriteByte (unsigned int bus, unsigned int dev, unsigned int func,
unsigned int reg_off, unsigned char byteval)
{
DWORD base_addr = 0x80000000;
base_addr |= ((bus & 0xFF) << 16); // bus #
base_addr |= ((dev & 0x1F) << 11); // device #
base_addr |= ((func & 0x07) << 8); // func #
IoOutputDword(0xcf8, (base_addr + (reg_off & 0xfc)));
IoOutputByte(0xcfc + (reg_off & 3), byteval);
}
WORD PciReadWord(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off)
{
DWORD base_addr = 0x80000000;
base_addr |= ((bus & 0xFF) << 16); // bus #
base_addr |= ((dev & 0x1F) << 11); // device #
base_addr |= ((func & 0x07) << 8); // func #
IoOutputDword(0xcf8, (base_addr + (reg_off & 0xfe)));
return IoInputWord(0xcfc + (reg_off & 1));
}
void PciWriteWord(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, WORD w)
{
DWORD base_addr = 0x80000000;
base_addr |= ((bus & 0xFF) << 16); // bus #
base_addr |= ((dev & 0x1F) << 11); // device #
base_addr |= ((func & 0x07) << 8); // func #
IoOutputDword(0xcf8, (base_addr + (reg_off & 0xfc)));
IoOutputWord(0xcfc + (reg_off & 1), w);
}
DWORD PciReadDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off)
{
DWORD base_addr = 0x80000000;
base_addr |= ((bus & 0xFF) << 16); // bus #
base_addr |= ((dev & 0x1F) << 11); // device #
base_addr |= ((func & 0x07) << 8); // func #
base_addr |= ((func & 0x07) << 8);
base_addr |= ((reg_off & 0xff));
IoOutputDword(0xcf8, base_addr);
return IoInputDword(0xcfc);
}
DWORD PciWriteDword(unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg_off, unsigned int dw)
{
DWORD base_addr = 0x80000000;
base_addr |= ((bus & 0xFF) << 16); // bus #
base_addr |= ((dev & 0x1F) << 11); // device #
base_addr |= ((func & 0x07) << 8); // func #
base_addr |= ((reg_off & 0xff));
IoOutputDword(0xcf8, base_addr );
IoOutputDword(0xcfc ,dw);
return 0;
}
#define RTC_REG_A 10
#define RTC_REG_B 11
#define RTC_REG_C 12
#define RTC_REG_D 13
#define RTC_FREQ_SELECT RTC_REG_A
#define RTC_CONTROL RTC_REG_B
#define RTC_INTR_FLAGS RTC_REG_C
/* On PCs, the checksum is built only over bytes 16..45 */
#define PC_CKS_RANGE_START 16
#define PC_CKS_RANGE_END 45
#define PC_CKS_LOC 46
#define RTC_RATE_1024HZ 0x06
#define RTC_REF_CLCK_32KHZ 0x20
#define RTC_FREQ_SELECT_DEFAULT (RTC_REF_CLCK_32KHZ | RTC_RATE_1024HZ)
#define RTC_24H 0x02
#define RTC_CONTROL_DEFAULT (RTC_24H)
// access to RTC CMOS memory
BYTE CMOS_READ(BYTE addr) {
IoOutputByte(0x70,addr);
return IoInputByte(0x71);
}
void CMOS_WRITE(BYTE val, BYTE addr) {
IoOutputByte(0x70,addr);
IoOutputByte(0x71,val);
}
void BiosCmosWrite(BYTE bAds, BYTE bData) {
IoOutputByte(0x70, bAds);
IoOutputByte(0x71, bData);
IoOutputByte(0x72, bAds);
IoOutputByte(0x73, bData);
}
BYTE BiosCmosRead(BYTE bAds)
{
IoOutputByte(0x72, bAds);
return IoInputByte(0x73);
}
int rtc_checksum_valid(int range_start, int range_end, int cks_loc)
{
int i;
unsigned sum, old_sum;
sum = 0;
for(i = range_start; i <= range_end; i++) {
sum += CMOS_READ(i);
}
sum = (~sum)&0x0ffff;
old_sum = ((CMOS_READ(cks_loc)<<8) | CMOS_READ(cks_loc+1))&0x0ffff;
return sum == old_sum;
}
void rtc_set_checksum(int range_start, int range_end, int cks_loc)
{
int i;
unsigned sum;
sum = 0;
for(i = range_start; i <= range_end; i++) {
sum += CMOS_READ(i);
}
sum = ~(sum & 0x0ffff);
CMOS_WRITE(((sum >> 8) & 0x0ff), cks_loc);
CMOS_WRITE(((sum >> 0) & 0x0ff), cks_loc+1);
}
void BootAGPBUSInitialization(void)
{
DWORD temp;
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x54, PciReadDword(BUS_0, DEV_1, FUNC_0, 0x54) | 0x88000000 );
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x64, (PciReadDword(BUS_0, DEV_0, FUNC_0, 0x64))| 0x88000000 );
temp = PciReadDword(BUS_0, DEV_0, FUNC_0, 0x6C);
IoOutputDword(0xcfc , temp & 0xFFFFFFFE);
IoOutputDword(0xcfc , temp );
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x80, 0x00000100);
}
void BootDetectMemorySize(void)
{
int i;
int result;
unsigned char *fillstring;
void *membasetop = (void*)((64*1024*1024));
void *membaselow = (void*)((0));
(*(unsigned int*)(0xFD000000 + 0x100200)) = 0x03070103 ;
(*(unsigned int*)(0xFD000000 + 0x100204)) = 0x11448000 ;
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x84, 0x7FFFFFF); // 128 MB
xbox_ram = 64;
fillstring = malloc(0x200);
memset(fillstring,0xAA,0x200);
memset(membasetop,0xAA,0x200);
asm volatile ("wbinvd\n");
if (!memcmp(membasetop,fillstring,0x200)) {
// Looks like there is memory .. maybe a 128MB box
memset(fillstring,0x55,0x200);
memset(membasetop,0x55,0x200);
asm volatile ("wbinvd\n");
if (!memcmp(membasetop,fillstring,0x200)) {
// Looks like there is memory
// now we are sure, we set memory
if (memcmp(membaselow,fillstring,0x200) == 0) {
// Hell, we find the Test-string at 0x0 too !
xbox_ram = 64;
} else {
xbox_ram = 128;
}
}
}
if (xbox_ram == 64) {
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x84, 0x3FFFFFF); // 64 MB
}
else if (xbox_ram == 128) {
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x84, 0x7FFFFFF); // 128 MB
}
free(fillstring);
}
void BootPciPeripheralInitialization()
{
__asm__ __volatile__ ( "cli" );
PciWriteDword(BUS_0, DEV_1, 0, 0x80, 2); // v1.1 2BL kill ROM area
if(PciReadByte(BUS_0, DEV_1, 0, 0x8)>=0xd1) { // check revision
PciWriteDword(BUS_0, DEV_1, 0, 0xc8, 0x8f00); // v1.1 2BL <-- death
}
// Bus 0, Device 0, Function 0 = PCI Bridge Device - Host Bridge
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x48, 0x00000114);
PciWriteDword(BUS_0, DEV_0, FUNC_0, 0x44, 0x80000000); // new 2003-01-23 ag trying to get single write actions on TSOP
PciWriteByte(BUS_0, DEV_0, FUNC_0, 0x87, 3); // kern 8001FC21
PciWriteByte(BUS_0, DEV_0, 8, 0, 0x42); // Xbeboot-compare
IoOutputByte(0x2e, 0x55);
IoOutputByte(0x2e, 0x26);
IoOutputByte(0x61, 0xff);
IoOutputByte(0x92, 0x01);
IoOutputByte(0xcf9, 0x0); // Reset Port
IoOutputByte(0x43, 0x36); // Timer 0 (system time): mode 3
IoOutputByte(0x40, 0xFF); // 18.2Hz (1.19318MHz/65535)
IoOutputByte(0x40, 0xFF);
IoOutputByte(0x43, 0x54); // Timer 1 (ISA refresh): mode 2
IoOutputByte(0x41, 18); // 64KHz (1.19318MHz/18)
IoOutputByte(0x00, 0); // clear base address 0
IoOutputByte(0x00, 0);
IoOutputByte(0x01, 0); // clear count 0
IoOutputByte(0x01, 0);
IoOutputByte(0x02, 0); // clear base address 1
IoOutputByte(0x02, 0 );
IoOutputByte(0x03, 0); // clear count 1
IoOutputByte(0x03, 0);
IoOutputByte(0x04, 0); // clear base address 2
IoOutputByte(0x04, 0);
IoOutputByte(0x05, 0); // clear count 2
IoOutputByte(0x05, 0);
IoOutputByte(0x06, 0); // clear base address 3
IoOutputByte(0x06, 0);
IoOutputByte(0x07, 0); // clear count 3
IoOutputByte(0x07, 0);
IoOutputByte(0x0B, 0x40); // set channel 0 to single mode, verify transfer
IoOutputByte(0x0B, 0x41); // set channel 1 to single mode, verify transfer
IoOutputByte(0x0B, 0x42); // set channel 2 to single mode, verify transfer
IoOutputByte(0x0B, 0x43); // set channel 3 to single mode, verify transfer
IoOutputByte(0x08, 0); // enable controller
IoOutputByte(0xC0, 0); // clear base address 0
IoOutputByte(0xC0, 0);
IoOutputByte(0xC2, 0); // clear count 0
IoOutputByte(0xC2, 0);
IoOutputByte(0xC4, 0); // clear base address 1
IoOutputByte(0xC4, 0);
IoOutputByte(0xC6, 0); // clear count 1
IoOutputByte(0xC6, 0);
IoOutputByte(0xC8, 0); // clear base address 2
IoOutputByte(0xC8, 0);
IoOutputByte(0xCA, 0); // clear count 2
IoOutputByte(0xCA, 0);
IoOutputByte(0xCC, 0); // clear base address 3
IoOutputByte(0xCC, 0);
IoOutputByte(0xCE, 0); // clear count 3
IoOutputByte(0xCE, 0);
IoOutputByte(0xD6, 0xC0); // set channel 0 to cascade mode
IoOutputByte(0xD6, 0xC1); // set channel 1 to single mode, verify transfer
IoOutputByte(0xD6, 0xC2); // set channel 2 to single mode, verify transfer
IoOutputByte(0xD6, 0xC3); // set channel 3 to single mode, verify transfer
IoOutputByte(0xD0, 0); // enable controller
IoOutputByte(0x0E, 0); // enable DMA0 channels
IoOutputByte(0xD4, 0); // clear chain 4 mask
/* Setup the real time clock */
CMOS_WRITE(RTC_CONTROL_DEFAULT, RTC_CONTROL);
/* Setup the frequency it operates at */
CMOS_WRITE(RTC_FREQ_SELECT_DEFAULT, RTC_FREQ_SELECT);
/* Make certain we have a valid checksum */
//rtc_set_checksum(PC_CKS_RANGE_START,
//PC_CKS_RANGE_END,PC_CKS_LOC);
/* Clear any pending interrupts */
(void) CMOS_READ(RTC_INTR_FLAGS);
// configure ACPI hardware to generate interrupt on PIC-chip pin6 action (via EXTSMI#)
IoOutputByte(0x80ce, 0x08); // from 2bl RI#
IoOutputByte(0x80c0, 0x08); // from 2bl SMBUSC
IoOutputByte(0x8004, IoInputByte(0x8004)|1); // KERN: SCI enable == SCI interrupt generated
IoOutputWord(0x8022, IoInputByte(0x8022)|2); // KERN: Interrupt enable register, b1 RESERVED in AMD docs
IoOutputWord(0x8023, IoInputByte(0x8023)|2); // KERN: Interrupt enable register, b1 RESERVED in AMD docs
IoOutputByte(0x8002, IoInputByte(0x8002)|1); // KERN: Enable SCI interrupt when timer status goes high
IoOutputWord(0x8028, IoInputByte(0x8028)|1); // KERN: setting readonly trap event???
I2CTransmitWord(0x10, 0x0b00); // Allow audio
//I2CTransmitWord(0x10, 0x0b01); // GAH!!! Audio Mute!
// Bus 0, Device 1, Function 0 = nForce HUB Interface - ISA Bridge
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x6c, 0x0e065491);
PciWriteByte(BUS_0, DEV_1, FUNC_0, 0x6a, 0x0003); // kern ??? gets us an int3? vsync req
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x64, 0x00000b0c);
PciWriteByte(BUS_0, DEV_1, FUNC_0, 0x81, PciReadByte(BUS_0, DEV_1, FUNC_0, 0x81)|8);
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x4c, 0x000f0000); // RTC clocks enable? 2Hz INT8?
// Bus 0, Device 9, Function 0 = nForce ATA Controller
PciWriteDword(BUS_0, DEV_9, FUNC_0, 0x20, 0x0000ff61); // (BMIBA) Set Busmaster regs I/O base address 0xff60
PciWriteDword(BUS_0, DEV_9, FUNC_0, 4, PciReadDword(BUS_0, DEV_9, FUNC_0, 4)|5); // 0x00b00005 );
PciWriteDword(BUS_0, DEV_9, FUNC_0, 8, PciReadDword(BUS_0, DEV_9, FUNC_0, 8)&0xfffffeff); // 0x01018ab1 ); // was fffffaff
PciWriteDword(BUS_0, DEV_9, FUNC_0, 0x58, 0x20202020); // kern1.1
PciWriteDword(BUS_0, DEV_9, FUNC_0, 0x60, 0x00000000); // kern1.1
PciWriteDword(BUS_0, DEV_9, FUNC_0, 0x50, 0x00000002); // without this there is no register footprint at IO 1F0
PciWriteDword(BUS_0, DEV_9, FUNC_0, 0x2c, 0x00000000); // frankenregister from xbe boot
PciWriteDword(BUS_0, DEV_9, FUNC_0, 0x40, 0x00000000); // frankenregister from xbe boot
// below reinstated by frankenregister compare with xbe boot
PciWriteDword(BUS_0, DEV_9, FUNC_0, 0x60, 0xC0C0C0C0); // kern1.1 <--- this was in kern1.1 but is FATAL for good HDD access
// Bus 0, Device 4, Function 0 = nForce MCP Networking Adapter - all verified with kern1.1
PciWriteDword(BUS_0, DEV_4, FUNC_0, 4, PciReadDword(BUS_0, DEV_4, FUNC_0, 4) | 7 );
PciWriteDword(BUS_0, DEV_4, FUNC_0, 0x10, 0xfef00000); // memory base address 0xfef00000
PciWriteDword(BUS_0, DEV_4, FUNC_0, 0x14, 0x0000e001); // I/O base address 0xe000
PciWriteDword(BUS_0, DEV_4, FUNC_0, 0x118-0xdc, (PciReadDword(BUS_0, DEV_4, FUNC_0, 0x3c) &0xffff0000) | 0x0004 );
// Bus 0, Device 2, Function 0 = nForce OHCI USB Controller - all verified with kern 1.1
PciWriteDword(BUS_0, DEV_2, FUNC_0, 4, PciReadDword(BUS_0, DEV_2, FUNC_0, 4) | 7 );
PciWriteDword(BUS_0, DEV_2, FUNC_0, 0x10, 0xfed00000); // memory base address 0xfed00000
PciWriteDword(BUS_0, DEV_2, FUNC_0, 0x3c, (PciReadDword(BUS_0, DEV_2, FUNC_0, 0x3c) &0xffff0000) | 0x0001 );
PciWriteDword(BUS_0, DEV_2, FUNC_0, 0x50, 0x0000000f);
// Bus 0, Device 3, Function 0 = nForce OHCI USB Controller - verified with kern1.1
PciWriteDword(BUS_0, DEV_3, FUNC_0, 4, PciReadDword(BUS_0, DEV_3, FUNC_0, 4) | 7 );
PciWriteDword(BUS_0, DEV_3, FUNC_0, 0x10, 0xfed08000); // memory base address 0xfed08000
PciWriteDword(BUS_0, DEV_3, FUNC_0, 0x3c, (PciReadDword(BUS_0, DEV_3, FUNC_0, 0x3c) &0xffff0000) | 0x0009 );
PciWriteDword(BUS_0, DEV_3, FUNC_0, 0x50, 0x00000030); // actually BYTE?
// Bus 0, Device 6, Function 0 = nForce Audio Codec Interface - verified with kern1.1
PciWriteDword(BUS_0, DEV_6, FUNC_0, 4, PciReadDword(BUS_0, DEV_6, FUNC_0, 4) | 7 );
PciWriteDword(BUS_0, DEV_6, FUNC_0, 0x10, (PciReadDword(BUS_0, DEV_6, FUNC_0, 0x10) &0xffff0000) | 0xd001 ); // MIXER at IO 0xd000
PciWriteDword(BUS_0, DEV_6, FUNC_0, 0x14, (PciReadDword(BUS_0, DEV_6, FUNC_0, 0x14) &0xffff0000) | 0xd201 ); // BusMaster at IO 0xD200
PciWriteDword(BUS_0, DEV_6, FUNC_0, 0x18, 0xfec00000); // memory base address 0xfec00000
// frankenregister from working Linux driver
PciWriteDword(BUS_0, DEV_6, FUNC_0, 8, 0x40100b1 );
PciWriteDword(BUS_0, DEV_6, FUNC_0, 0xc, 0x800000 );
PciWriteDword(BUS_0, DEV_6, FUNC_0, 0x3c, 0x05020106 );
PciWriteDword(BUS_0, DEV_6, FUNC_0, 0x44, 0x20001 );
PciWriteDword(BUS_0, DEV_6, FUNC_0, 0x4c, 0x107 );
// Bus 0, Device 5, Function 0 = nForce MCP APU
PciWriteDword(BUS_0, DEV_5, FUNC_0, 4, PciReadDword(BUS_0, DEV_5, FUNC_0, 4) | 7 );
PciWriteDword(BUS_0, DEV_5, FUNC_0, 0x3c, (PciReadDword(BUS_0, DEV_5, FUNC_0, 0x3c) &0xffff0000) | 0x0005 );
PciWriteDword(BUS_0, DEV_5, FUNC_0, 0x10, 0xfe800000); // memory base address 0xfe800000
// Bus 0, Device 1, Function 0 = nForce HUB Interface - ISA Bridge
PciWriteDword(BUS_0, DEV_1, FUNC_0, 0x8c, (PciReadDword(BUS_0, DEV_1, FUNC_0, 0x8c) &0xfbffffff) | 0x08000000 );
// ACPI pin init
IoOutputDword(0x80b4, 0xffff); // any interrupt resets ACPI system inactivity timer
IoOutputByte(0x80cc, 0x08); // Set EXTSMI# pin to be pin function
IoOutputByte(0x80cd, 0x08); // Set PRDY pin on ACPI to be PRDY function
IoOutputByte(0x80cf, 0x08); // Set C32KHZ pin to be pin function
IoOutputWord(0x8020, IoInputWord(0x8020)|0x200); // ack any preceding ACPI int
// Bus 0, Device 1e, Function 0 = nForce AGP Host to PCI Bridge
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 4, PciReadDword(BUS_0, DEV_1e, FUNC_0, 4) | 7 );
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x18, (PciReadDword(BUS_0, DEV_1e, FUNC_0, 0x18) &0xffffff00));
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x3c, 7); // trying to get video irq
// frankenregister xbe load correction to match cromwell load
// controls requests for memory regions
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x0c, 0xff019ee7);
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x10, 0xbcfaf7e7);
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x14, 0x0101fafa);
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x1c, 0x02a000f0); // Coud this be the BASE Video Address ?
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x20, 0xfdf0fd00);
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x24, 0xf7f0f000);
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x28, 0x8e7ffcff);
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x2c, 0xf8bfef87);
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x30, 0xdf758fa3);
PciWriteDword(BUS_0, DEV_1e, FUNC_0, 0x38, 0xb785fccc);
// Bus 1, Device 0, Function 0 = NV2A GeForce3 Integrated GPU
PciWriteDword(BUS_1, DEV_0, FUNC_0, 4, PciReadDword(BUS_1, DEV_0, FUNC_0, 4) | 7 );
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x3c, (PciReadDword(BUS_1, DEV_0, FUNC_0, 0x3c) &0xffff0000) | 0x0103 ); // should get vid irq!!
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x4c, 0x00000114);
// frankenregisters so Xromwell matches Cromwell
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x0c, 0x0);
PciWriteDword(BUS_1, DEV_0, FUNC_0, 0x18, 0x08);
}

View file

@ -1,4 +0,0 @@
subdir += host core sys
#O_TARGET := BootUsbOhci.o
include $(TOPDIR)/Rules.make

View file

@ -1,6 +0,0 @@
O_TARGET := message.o hcd.o hcd-pci.o hub.o usb.o config.o urb.o buffer_simple.o urb.o usb-debug.o
#O_TARGET := urb.o
include $(TOPDIR)/Rules.make

View file

@ -1,42 +0,0 @@
/*
* buffer_simple.c -- replacement for usb/core/buffer.c
*
* (c) Georg Acher, georg@acher.org
*
*/
#include "../usb_wrapper.h"
#define __KERNEL__
#define CONFIG_PCI
#include "hcd.h"
/*------------------------------------------------------------------------*/
int hcd_buffer_create (struct usb_hcd *hcd)
{
return 0;
}
/*------------------------------------------------------------------------*/
void hcd_buffer_destroy (struct usb_hcd *hcd)
{
}
/*------------------------------------------------------------------------*/
void *hcd_buffer_alloc (
struct usb_bus *bus,
size_t size,
int mem_flags,
dma_addr_t *dma
)
{
return kmalloc(size,0);
}
/*------------------------------------------------------------------------*/
void hcd_buffer_free (
struct usb_bus *bus,
size_t size,
void *addr,
dma_addr_t dma
)
{
kfree(addr);
}

View file

@ -1,508 +0,0 @@
#if 0
#include <linux/usb.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#else
#include "../usb_wrapper.h"
#endif
#define USB_MAXALTSETTING 128 /* Hard limit */
#define USB_MAXENDPOINTS 30 /* Hard limit */
/* these maximums are arbitrary */
#define USB_MAXCONFIG 8
#define USB_ALTSETTINGALLOC 4
#define USB_MAXINTERFACES 32
static int usb_parse_endpoint(struct usb_host_endpoint *endpoint, unsigned char *buffer, int size)
{
struct usb_descriptor_header *header;
unsigned char *begin;
int parsed = 0, len, numskipped;
header = (struct usb_descriptor_header *)buffer;
/* Everything should be fine being passed into here, but we sanity */
/* check JIC */
if (header->bLength > size) {
err("ran out of descriptors parsing");
return -1;
}
if (header->bDescriptorType != USB_DT_ENDPOINT) {
warn("unexpected descriptor 0x%X, expecting endpoint, 0x%X",
header->bDescriptorType, USB_DT_ENDPOINT);
return parsed;
}
if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)
memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
else
memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_SIZE);
le16_to_cpus(&endpoint->desc.wMaxPacketSize);
buffer += header->bLength;
size -= header->bLength;
parsed += header->bLength;
/* Skip over the rest of the Class Specific or Vendor Specific */
/* descriptors */
begin = buffer;
numskipped = 0;
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength < 2) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
dbg("skipping descriptor 0x%X",
header->bDescriptorType);
numskipped++;
buffer += header->bLength;
size -= header->bLength;
parsed += header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for drivers */
/* to later parse */
len = (int)(buffer - begin);
if (!len) {
endpoint->extra = NULL;
endpoint->extralen = 0;
return parsed;
}
endpoint->extra = kmalloc(len, GFP_KERNEL);
if (!endpoint->extra) {
err("couldn't allocate memory for endpoint extra descriptors");
endpoint->extralen = 0;
return parsed;
}
memcpy(endpoint->extra, begin, len);
endpoint->extralen = len;
return parsed;
}
static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size)
{
int i, len, numskipped, retval, parsed = 0;
struct usb_descriptor_header *header;
struct usb_host_interface *ifp;
unsigned char *begin;
interface->act_altsetting = 0;
interface->num_altsetting = 0;
interface->max_altsetting = USB_ALTSETTINGALLOC;
device_initialize(&interface->dev);
interface->altsetting = kmalloc(sizeof(*interface->altsetting) * interface->max_altsetting,
GFP_KERNEL);
if (!interface->altsetting) {
err("couldn't kmalloc interface->altsetting");
return -1;
}
while (size > 0) {
struct usb_interface_descriptor *d;
if (interface->num_altsetting >= interface->max_altsetting) {
struct usb_host_interface *ptr;
int oldmas;
oldmas = interface->max_altsetting;
interface->max_altsetting += USB_ALTSETTINGALLOC;
if (interface->max_altsetting > USB_MAXALTSETTING) {
warn("too many alternate settings (incr %d max %d)\n",
USB_ALTSETTINGALLOC, USB_MAXALTSETTING);
return -1;
}
ptr = kmalloc(sizeof(*ptr) * interface->max_altsetting, GFP_KERNEL);
if (ptr == NULL) {
err("couldn't kmalloc interface->altsetting");
return -1;
}
memcpy(ptr, interface->altsetting, sizeof(*interface->altsetting) * oldmas);
kfree(interface->altsetting);
interface->altsetting = ptr;
}
ifp = interface->altsetting + interface->num_altsetting;
ifp->endpoint = NULL;
ifp->extra = NULL;
ifp->extralen = 0;
interface->num_altsetting++;
memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
/* Skip over the interface */
buffer += ifp->desc.bLength;
parsed += ifp->desc.bLength;
size -= ifp->desc.bLength;
begin = buffer;
numskipped = 0;
/* Skip over any interface, class or vendor descriptors */
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength < 2) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
numskipped++;
buffer += header->bLength;
parsed += header->bLength;
size -= header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific interface descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for */
/* drivers to later parse */
len = (int)(buffer - begin);
if (len) {
ifp->extra = kmalloc(len, GFP_KERNEL);
if (!ifp->extra) {
err("couldn't allocate memory for interface extra descriptors");
ifp->extralen = 0;
return -1;
}
memcpy(ifp->extra, begin, len);
ifp->extralen = len;
}
/* Did we hit an unexpected descriptor? */
header = (struct usb_descriptor_header *)buffer;
if ((size >= sizeof(struct usb_descriptor_header)) &&
((header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE)))
return parsed;
if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) {
warn("too many endpoints");
return -1;
}
ifp->endpoint = (struct usb_host_endpoint *)
kmalloc(ifp->desc.bNumEndpoints *
sizeof(struct usb_host_endpoint), GFP_KERNEL);
if (!ifp->endpoint) {
err("out of memory");
return -1;
}
memset(ifp->endpoint, 0, ifp->desc.bNumEndpoints *
sizeof(struct usb_host_endpoint));
for (i = 0; i < ifp->desc.bNumEndpoints; i++) {
header = (struct usb_descriptor_header *)buffer;
if (header->bLength > size) {
err("ran out of descriptors parsing");
return -1;
}
retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
if (retval < 0)
return retval;
buffer += retval;
parsed += retval;
size -= retval;
}
/* We check to see if it's an alternate to this one */
d = (struct usb_interface_descriptor *)buffer;
if (size < USB_DT_INTERFACE_SIZE
|| d->bDescriptorType != USB_DT_INTERFACE
|| !d->bAlternateSetting)
return parsed;
}
return parsed;
}
int usb_parse_configuration(struct usb_host_config *config, char *buffer)
{
int i, retval, size;
struct usb_descriptor_header *header;
memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
le16_to_cpus(&config->desc.wTotalLength);
size = config->desc.wTotalLength;
if (config->desc.bNumInterfaces > USB_MAXINTERFACES) {
warn("too many interfaces");
return -1;
}
config->interface = (struct usb_interface *)
kmalloc(config->desc.bNumInterfaces *
sizeof(struct usb_interface), GFP_KERNEL);
dbg("kmalloc IF %p, numif %i", config->interface, config->desc.bNumInterfaces);
if (!config->interface) {
err("out of memory");
return -1;
}
memset(config->interface, 0,
config->desc.bNumInterfaces * sizeof(struct usb_interface));
buffer += config->desc.bLength;
size -= config->desc.bLength;
config->extra = NULL;
config->extralen = 0;
for (i = 0; i < config->desc.bNumInterfaces; i++) {
int numskipped, len;
char *begin;
/* Skip over the rest of the Class Specific or Vendor */
/* Specific descriptors */
begin = buffer;
numskipped = 0;
while (size >= sizeof(struct usb_descriptor_header)) {
header = (struct usb_descriptor_header *)buffer;
if ((header->bLength > size) || (header->bLength < 2)) {
err("invalid descriptor length of %d", header->bLength);
return -1;
}
/* If we find another "proper" descriptor then we're done */
if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
(header->bDescriptorType == USB_DT_INTERFACE) ||
(header->bDescriptorType == USB_DT_CONFIG) ||
(header->bDescriptorType == USB_DT_DEVICE))
break;
dbg("skipping descriptor 0x%X", header->bDescriptorType);
numskipped++;
buffer += header->bLength;
size -= header->bLength;
}
if (numskipped)
dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
/* Copy any unknown descriptors into a storage area for */
/* drivers to later parse */
len = (int)(buffer - begin);
if (len) {
if (config->extralen) {
warn("extra config descriptor");
} else {
config->extra = kmalloc(len, GFP_KERNEL);
if (!config->extra) {
err("couldn't allocate memory for config extra descriptors");
config->extralen = 0;
return -1;
}
memcpy(config->extra, begin, len);
config->extralen = len;
}
}
retval = usb_parse_interface(config->interface + i, buffer, size);
if (retval < 0)
return retval;
buffer += retval;
size -= retval;
}
return size;
}
// hub-only!! ... and only exported for reset/reinit path.
// otherwise used internally on disconnect/destroy path
void usb_destroy_configuration(struct usb_device *dev)
{
int c, i, j, k;
if (!dev->config)
return;
if (dev->rawdescriptors) {
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
kfree(dev->rawdescriptors[i]);
kfree(dev->rawdescriptors);
}
for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
struct usb_host_config *cf = &dev->config[c];
if (!cf->interface)
break;
for (i = 0; i < cf->desc.bNumInterfaces; i++) {
struct usb_interface *ifp =
&cf->interface[i];
if (!ifp->altsetting)
break;
for (j = 0; j < ifp->num_altsetting; j++) {
struct usb_host_interface *as =
&ifp->altsetting[j];
if(as->extra) {
kfree(as->extra);
}
if (!as->endpoint)
break;
for(k = 0; k < as->desc.bNumEndpoints; k++) {
if(as->endpoint[k].extra) {
kfree(as->endpoint[k].extra);
}
}
kfree(as->endpoint);
}
kfree(ifp->altsetting);
}
kfree(cf->interface);
}
kfree(dev->config);
}
// hub-only!! ... and only in reset path, or usb_new_device()
// (used by real hubs and virtual root hubs)
int usb_get_configuration(struct usb_device *dev)
{
int result;
unsigned int cfgno, length;
unsigned char *buffer;
unsigned char *bigbuffer;
struct usb_config_descriptor *desc;
if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
warn("too many configurations");
return -EINVAL;
}
if (dev->descriptor.bNumConfigurations < 1) {
warn("not enough configurations");
return -EINVAL;
}
dev->config = (struct usb_host_config *)
kmalloc(dev->descriptor.bNumConfigurations *
sizeof(struct usb_host_config), GFP_KERNEL);
if (!dev->config) {
err("out of memory");
return -ENOMEM;
}
memset(dev->config, 0, dev->descriptor.bNumConfigurations *
sizeof(struct usb_host_config));
dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
dev->descriptor.bNumConfigurations, GFP_KERNEL);
if (!dev->rawdescriptors) {
err("out of memory");
return -ENOMEM;
}
buffer = kmalloc(8, GFP_KERNEL);
if (!buffer) {
err("unable to allocate memory for configuration descriptors");
return -ENOMEM;
}
desc = (struct usb_config_descriptor *)buffer;
for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
/* We grab the first 8 bytes so we know how long the whole */
/* configuration is */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
if (result < 8) {
if (result < 0)
err("unable to get descriptor");
else {
err("config descriptor too short (expected %i, got %i)", 8, result);
result = -EINVAL;
}
goto err;
}
/* Get the full buffer */
length = le16_to_cpu(desc->wTotalLength);
bigbuffer = kmalloc(length, GFP_KERNEL);
if (!bigbuffer) {
err("unable to allocate memory for configuration descriptors");
result = -ENOMEM;
goto err;
}
/* Now that we know the length, get the whole thing */
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);
if (result < 0) {
err("couldn't get all of config descriptors");
kfree(bigbuffer);
goto err;
}
if (result < length) {
err("config descriptor too short (expected %i, got %i)", length, result);
result = -EINVAL;
kfree(bigbuffer);
goto err;
}
dev->rawdescriptors[cfgno] = bigbuffer;
result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
if (result > 0)
dbg("descriptor data left");
else if (result < 0) {
result = -EINVAL;
goto err;
}
}
kfree(buffer);
return 0;
err:
kfree(buffer);
dev->descriptor.bNumConfigurations = cfgno;
return result;
}

View file

@ -1,365 +0,0 @@
/*
* (C) Copyright David Brownell 2000-2002
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if 0
#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/usb.h>
#include "hcd.h"
#else
#define DEBUG
#include "../usb_wrapper.h"
#include "hcd.h"
#endif
/* PCI-based HCs are normal, but custom bus glue should be ok */
/*-------------------------------------------------------------------------*/
/* configure so an HC device and id are always provided */
/* always called with process context; sleeping is OK */
/**
* usb_hcd_pci_probe - initialize PCI-based HCDs
* @dev: USB Host Controller being probed
* @id: pci hotplug id connecting controller to HCD framework
* Context: !in_interrupt()
*
* Allocates basic PCI resources for this USB host controller, and
* then invokes the start() method for the HCD associated with it
* through the hotplug entry's driver_data.
*
* Store this function in the HCD's struct pci_driver as probe().
*/
int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
struct hc_driver *driver;
unsigned long resource, len;
void *base;
struct usb_hcd *hcd;
int retval, region;
char buf [8];
//char *bufp = buf;
if (usb_disabled())
return -ENODEV;
if (!id || !(driver = (struct hc_driver *) id->driver_data))
return -EINVAL;
if (pci_enable_device (dev) < 0)
return -ENODEV;
if (!dev->irq) {
err ("Found HC with no IRQ. Check BIOS/PCI %s setup!",
dev->slot_name);
return -ENODEV;
}
if (driver->flags & HCD_MEMORY) { // EHCI, OHCI
region = 0;
resource = pci_resource_start (dev, 0);
len = pci_resource_len (dev, 0);
if (!request_mem_region (resource, len, driver->description)) {
dbg ("controller already in use");
return -EBUSY;
}
base = ioremap_nocache (resource, len);
if (base == NULL) {
dbg ("error mapping memory");
retval = -EFAULT;
clean_1:
release_mem_region (resource, len);
err ("init %s fail, %d", dev->slot_name, retval);
return retval;
}
} else { // UHCI
resource = len = 0;
for (region = 0; region < PCI_ROM_RESOURCE; region++) {
if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
continue;
resource = pci_resource_start (dev, region);
len = pci_resource_len (dev, region);
if (request_region (resource, len,
driver->description))
break;
}
if (region == PCI_ROM_RESOURCE) {
dbg ("no i/o regions available");
return -EBUSY;
}
base = (void *) resource;
}
// driver->start(), later on, will transfer device from
// control by SMM/BIOS to control by Linux (if needed)
pci_set_master (dev);
hcd = driver->hcd_alloc ();
if (hcd == NULL){
dbg ("hcd alloc fail");
retval = -ENOMEM;
clean_2:
if (driver->flags & HCD_MEMORY) {
iounmap (base);
goto clean_1;
} else {
release_region (resource, len);
err ("init %s fail, %d", dev->slot_name, retval);
return retval;
}
}
pci_set_drvdata (dev, hcd);
hcd->driver = driver;
hcd->description = driver->description;
hcd->pdev = dev;
hcd->self.bus_name = dev->slot_name;
hcd->product_desc = dev->dev.name;
hcd->self.controller = &dev->dev;
hcd->controller = hcd->self.controller;
if ((retval = hcd_buffer_create (hcd)) != 0) {
clean_3:
driver->hcd_free (hcd);
goto clean_2;
}
dev_info (hcd->controller, "%s\n", hcd->product_desc);
#ifndef __sparc__
sprintf (buf, "%d", dev->irq);
#else
bufp = __irq_itoa(dev->irq);
#endif
if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
!= 0) {
dev_err (hcd->controller,
"request interrupt %s failed\n", bufp);
retval = -EBUSY;
goto clean_3;
}
hcd->irq = dev->irq;
hcd->regs = base;
hcd->region = region;
dev_info (hcd->controller, "irq %s, %s %p\n", bufp,
(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
base);
usb_bus_init (&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.hcpriv = (void *) hcd;
INIT_LIST_HEAD (&hcd->dev_list);
usb_register_bus (&hcd->self);
if ((retval = driver->start (hcd)) < 0)
usb_hcd_pci_remove (dev);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_probe);
/* may be called without controller electrically present */
/* may be called with controller, bus, and devices active */
/**
* usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
* @dev: USB Host Controller being removed
* Context: !in_interrupt()
*
* Reverses the effect of usb_hcd_pci_probe(), first invoking
* the HCD's stop() method. It is always called from a thread
* context, normally "rmmod", "apmd", or something similar.
*
* Store this function in the HCD's struct pci_driver as remove().
*/
void usb_hcd_pci_remove (struct pci_dev *dev)
{
struct usb_hcd *hcd;
struct usb_device *hub;
hcd = pci_get_drvdata(dev);
if (!hcd)
return;
dev_info (hcd->controller, "remove, state %x\n", hcd->state);
if (in_interrupt ())
BUG ();
hub = hcd->self.root_hub;
hcd->state = USB_STATE_QUIESCING;
dev_dbg (hcd->controller, "roothub graceful disconnect\n");
usb_disconnect (&hub);
hcd->driver->stop (hcd);
hcd_buffer_destroy (hcd);
hcd->state = USB_STATE_HALT;
pci_set_drvdata (dev, 0);
free_irq (hcd->irq, hcd);
if (hcd->driver->flags & HCD_MEMORY) {
iounmap (hcd->regs);
release_mem_region (pci_resource_start (dev, 0),
pci_resource_len (dev, 0));
} else {
release_region (pci_resource_start (dev, hcd->region),
pci_resource_len (dev, hcd->region));
}
usb_deregister_bus (&hcd->self);
if (atomic_read (&hcd->self.refcnt) != 1) {
dev_warn (hcd->controller,
"dangling refs (%d) to bus %d!\n",
atomic_read (&hcd->self.refcnt) - 1,
hcd->self.busnum);
}
hcd->driver->hcd_free (hcd);
}
EXPORT_SYMBOL (usb_hcd_pci_remove);
#ifdef CONFIG_PM
/*
* Some "sleep" power levels imply updating struct usb_driver
* to include a callback asking hcds to do their bit by checking
* if all the drivers can suspend. Gets involved with remote wakeup.
*
* If there are pending urbs, then HCs will need to access memory,
* causing extra power drain. New sleep()/wakeup() PM calls might
* be needed, beyond PCI suspend()/resume(). The root hub timer
* still be accessing memory though ...
*
* FIXME: USB should have some power budgeting support working with
* all kinds of hubs.
*
* FIXME: This assumes only D0->D3 suspend and D3->D0 resume.
* D1 and D2 states should do something, yes?
*
* FIXME: Should provide generic enable_wake(), calling pci_enable_wake()
* for all supported states, so that USB remote wakeup can work for any
* devices that support it (and are connected via powered hubs).
*
* FIXME: resume doesn't seem to work right any more...
*/
// 2.4 kernels have issued concurrent resumes (w/APM)
// we defend against that error; PCI doesn't yet.
/**
* usb_hcd_pci_suspend - power management suspend of a PCI-based HCD
* @dev: USB Host Controller being suspended
*
* Store this function in the HCD's struct pci_driver as suspend().
*/
int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
{
struct usb_hcd *hcd;
int retval;
hcd = pci_get_drvdata(dev);
dev_info (hcd->controller, "suspend to state %d\n", state);
pci_save_state (dev, hcd->pci_state);
// FIXME for all connected devices, leaf-to-root:
// driver->suspend()
// proposed "new 2.5 driver model" will automate that
/* driver may want to disable DMA etc */
retval = hcd->driver->suspend (hcd, state);
hcd->state = USB_STATE_SUSPENDED;
pci_set_power_state (dev, state);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_suspend);
/**
* usb_hcd_pci_resume - power management resume of a PCI-based HCD
* @dev: USB Host Controller being resumed
*
* Store this function in the HCD's struct pci_driver as resume().
*/
int usb_hcd_pci_resume (struct pci_dev *dev)
{
struct usb_hcd *hcd;
int retval;
hcd = pci_get_drvdata(dev);
dev_info (hcd->controller, "resume\n");
/* guard against multiple resumes (APM bug?) */
atomic_inc (&hcd->resume_count);
if (atomic_read (&hcd->resume_count) != 1) {
dev_err (hcd->controller, "concurrent PCI resumes\n");
retval = 0;
goto done;
}
retval = -EBUSY;
if (hcd->state != USB_STATE_SUSPENDED) {
dev_dbg (hcd->controller, "can't resume, not suspended!\n");
goto done;
}
hcd->state = USB_STATE_RESUMING;
pci_set_power_state (dev, 0);
pci_restore_state (dev, hcd->pci_state);
retval = hcd->driver->resume (hcd);
if (!HCD_IS_RUNNING (hcd->state)) {
dev_dbg (hcd->controller, "resume fail, retval %d\n", retval);
usb_hc_died (hcd);
// FIXME: recover, reset etc.
} else {
// FIXME for all connected devices, root-to-leaf:
// driver->resume ();
// proposed "new 2.5 driver model" will automate that
}
done:
atomic_dec (&hcd->resume_count);
return retval;
}
EXPORT_SYMBOL (usb_hcd_pci_resume);
#endif /* CONFIG_PM */

File diff suppressed because it is too large Load diff

View file

@ -1,430 +0,0 @@
/*
* Copyright (c) 2001-2002 by David Brownell
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef __KERNEL__
/* This file contains declarations of usbcore internals that are mostly
* used or exposed by Host Controller Drivers.
*/
/*
* USB Packet IDs (PIDs)
*/
#define USB_PID_UNDEF_0 0xf0
#define USB_PID_OUT 0xe1
#define USB_PID_ACK 0xd2
#define USB_PID_DATA0 0xc3
#define USB_PID_PING 0xb4 /* USB 2.0 */
#define USB_PID_SOF 0xa5
#define USB_PID_NYET 0x96 /* USB 2.0 */
#define USB_PID_DATA2 0x87 /* USB 2.0 */
#define USB_PID_SPLIT 0x78 /* USB 2.0 */
#define USB_PID_IN 0x69
#define USB_PID_NAK 0x5a
#define USB_PID_DATA1 0x4b
#define USB_PID_PREAMBLE 0x3c /* Token mode */
#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */
#define USB_PID_SETUP 0x2d
#define USB_PID_STALL 0x1e
#define USB_PID_MDATA 0x0f /* USB 2.0 */
/*-------------------------------------------------------------------------*/
/*
* USB Host Controller Driver (usb_hcd) framework
*
* Since "struct usb_bus" is so thin, you can't share much code in it.
* This framework is a layer over that, and should be more sharable.
*/
/*-------------------------------------------------------------------------*/
struct usb_hcd { /* usb_bus.hcpriv points to this */
/*
* housekeeping
*/
struct usb_bus self; /* hcd is-a bus */
const char *product_desc; /* product/vendor string */
const char *description; /* "ehci-hcd" etc */
struct timer_list rh_timer; /* drives root hub */
struct list_head dev_list; /* devices on this bus */
struct work_struct work;
/*
* hardware info/state
*/
struct hc_driver *driver; /* hw-specific hooks */
int irq; /* irq allocated */
void *regs; /* device memory/io */
struct device *controller; /* handle to hardware */
/* a few non-PCI controllers exist, mostly for OHCI */
struct pci_dev *pdev; /* pci is typical */
#ifdef CONFIG_PCI
int region; /* pci region for regs */
u32 pci_state [16]; /* for PM state save */
atomic_t resume_count; /* multiple resumes issue */
#endif
#define HCD_BUFFER_POOLS 4
struct pci_pool *pool [HCD_BUFFER_POOLS];
int state;
# define __ACTIVE 0x01
# define __SLEEPY 0x02
# define __SUSPEND 0x04
# define __TRANSIENT 0x80
# define USB_STATE_HALT 0
# define USB_STATE_RUNNING (__ACTIVE)
# define USB_STATE_READY (__ACTIVE|__SLEEPY)
# define USB_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
# define USB_STATE_RESUMING (__SUSPEND|__TRANSIENT)
# define USB_STATE_SUSPENDED (__SUSPEND)
#define HCD_IS_RUNNING(state) ((state) & __ACTIVE)
#define HCD_IS_SUSPENDED(state) ((state) & __SUSPEND)
/* more shared queuing code would be good; it should support
* smarter scheduling, handle transaction translators, etc;
* input size of periodic table to an interrupt scheduler.
* (ohci 32, uhci 1024, ehci 256/512/1024).
*/
};
/* 2.4 does this a bit differently ... */
static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
{
return &hcd->self;
}
struct hcd_dev { /* usb_device.hcpriv points to this */
struct list_head dev_list; /* on this hcd */
struct list_head urb_list; /* pending on this dev */
/* per-configuration HC/HCD state, such as QH or ED */
void *ep[32];
};
// urb.hcpriv is really hardware-specific
struct hcd_timeout { /* timeouts we allocate */
struct list_head timeout_list;
struct timer_list timer;
};
/*-------------------------------------------------------------------------*/
/*
* FIXME usb_operations should vanish or become hc_driver,
* when usb_bus and usb_hcd become the same thing.
*/
struct usb_operations {
int (*allocate)(struct usb_device *);
int (*deallocate)(struct usb_device *);
int (*get_frame_number) (struct usb_device *usb_dev);
int (*submit_urb) (struct urb *urb, int mem_flags);
int (*unlink_urb) (struct urb *urb);
/* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
int mem_flags,
dma_addr_t *dma);
void (*buffer_free)(struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
void (*disable)(struct usb_device *udev, int bEndpointAddress);
};
/* each driver provides one of these, and hardware init support */
struct pt_regs;
struct hc_driver {
const char *description; /* "ehci-hcd" etc */
/* irq handler */
void (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
int flags;
#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
#define HCD_USB11 0x0010 /* USB 1.1 */
#define HCD_USB2 0x0020 /* USB 2.0 */
/* called to init HCD and root hub */
int (*start) (struct usb_hcd *hcd);
/* called after all devices were suspended */
int (*suspend) (struct usb_hcd *hcd, u32 state);
/* called before any devices get resumed */
int (*resume) (struct usb_hcd *hcd);
/* cleanly make HCD stop writing memory and doing I/O */
void (*stop) (struct usb_hcd *hcd);
/* return current frame number */
int (*get_frame_number) (struct usb_hcd *hcd);
/* memory lifecycle */
struct usb_hcd *(*hcd_alloc) (void);
void (*hcd_free) (struct usb_hcd *hcd);
/* manage i/o requests, device state */
int (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
int mem_flags);
int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
void (*endpoint_disable)(struct usb_hcd *hcd,
struct hcd_dev *dev, int bEndpointAddress);
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
int (*hub_control) (struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
};
extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
extern void usb_bus_init (struct usb_bus *bus);
extern void usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb);
#ifdef CONFIG_PCI
struct pci_dev;
struct pci_device_id;
extern int usb_hcd_pci_probe (struct pci_dev *dev,
const struct pci_device_id *id);
extern void usb_hcd_pci_remove (struct pci_dev *dev);
#ifdef CONFIG_PM
// FIXME: see Documentation/power/pci.txt (2.4.6 and later?)
// extern int usb_hcd_pci_save_state (struct pci_dev *dev, u32 state);
extern int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state);
extern int usb_hcd_pci_resume (struct pci_dev *dev);
// extern int usb_hcd_pci_enable_wake (struct pci_dev *dev, u32 state, int flg);
#endif /* CONFIG_PM */
#endif /* CONFIG_PCI */
/* pci-ish (pdev null is ok) buffer alloc/mapping support */
int hcd_buffer_create (struct usb_hcd *hcd);
void hcd_buffer_destroy (struct usb_hcd *hcd);
void *hcd_buffer_alloc (struct usb_bus *bus, size_t size,
int mem_flags, dma_addr_t *dma);
void hcd_buffer_free (struct usb_bus *bus, size_t size,
void *addr, dma_addr_t dma);
/* generic bus glue, needed for host controllers that don't use PCI */
extern struct usb_operations usb_hcd_operations;
extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
extern void usb_hc_died (struct usb_hcd *hcd);
/* -------------------------------------------------------------------------- */
/* Enumeration is only for the hub driver, or HCD virtual root hubs */
extern int usb_new_device(struct usb_device *dev, struct device *parent);
extern void usb_connect(struct usb_device *dev);
extern void usb_disconnect(struct usb_device **);
/* exported to hub driver ONLY to support usb_reset_device () */
extern int usb_get_configuration(struct usb_device *dev);
extern void usb_set_maxpacket(struct usb_device *dev);
extern void usb_destroy_configuration(struct usb_device *dev);
extern int usb_set_address(struct usb_device *dev);
/* use these only before the device's address has been set */
#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30))
#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | USB_DIR_IN)
/*-------------------------------------------------------------------------*/
/*
* HCD Root Hub support
*/
#include "hub.h"
/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
#define DeviceRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
#define DeviceOutRequest \
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8)
#define InterfaceRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define EndpointRequest \
((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
#define EndpointOutRequest \
((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8)
/* table 9.6 standard features */
#define DEVICE_REMOTE_WAKEUP 1
#define ENDPOINT_HALT 0
/* class requests from the USB 2.0 hub spec, table 11-15 */
/* GetBusState and SetHubDescriptor are optional, omitted */
#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE)
#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE)
#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR)
#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS)
#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS)
#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE)
#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
/*-------------------------------------------------------------------------*/
/*
* Generic bandwidth allocation constants/support
*/
#define FRAME_TIME_USECS 1000L
#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
/* Trying not to use worst-case bit-stuffing
of (7/6 * 8 * bytecount) = 9.33 * bytecount */
/* bytecount = data payload byte count */
#define NS_TO_US(ns) ((ns + 500L) / 1000L)
/* convert & round nanoseconds to microseconds */
extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
int bustime, int isoc);
extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb,
int isoc);
/*
* Full/low speed bandwidth allocation constants/support.
*/
#define BW_HOST_DELAY 1000L /* nanoseconds */
#define BW_HUB_LS_SETUP 333L /* nanoseconds */
/* 4 full-speed bit times (est.) */
#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
/*
* Ceiling microseconds (typical) for that many bytes at high speed
* ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
* to preallocate bandwidth)
*/
#define USB2_HOST_DELAY 5 /* nsec, guess */
#define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \
+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+ USB2_HOST_DELAY)
#define HS_USECS_ISO(bytes) NS_TO_US ( ((long)(38 * 8 * 2.083)) \
+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
+ USB2_HOST_DELAY)
extern long usb_calc_bus_time (int speed, int is_input,
int isoc, int bytecount);
/*-------------------------------------------------------------------------*/
extern struct usb_bus *usb_alloc_bus (struct usb_operations *);
extern void usb_free_bus (struct usb_bus *);
extern void usb_register_bus (struct usb_bus *);
extern void usb_deregister_bus (struct usb_bus *);
extern int usb_register_root_hub (struct usb_device *usb_dev,
struct device *parent_dev);
/* for portability to 2.4, hcds should call this */
static inline int hcd_register_root (struct usb_hcd *hcd)
{
return usb_register_root_hub (
hcd_to_bus (hcd)->root_hub, hcd->controller);
}
/*-------------------------------------------------------------------------*/
/* exported only within usbcore */
extern struct list_head usb_bus_list;
extern struct semaphore usb_bus_list_lock;
extern void usb_bus_get (struct usb_bus *bus);
extern void usb_bus_put (struct usb_bus *bus);
extern int usb_find_interface_driver (struct usb_device *dev,
struct usb_interface *interface);
#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep)))
#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
/*
* USB device fs stuff
*/
#ifdef CONFIG_USB_DEVICEFS
/*
* these are expected to be called from the USB core/hub thread
* with the kernel lock held
*/
extern void usbfs_add_bus(struct usb_bus *bus);
extern void usbfs_remove_bus(struct usb_bus *bus);
extern void usbfs_add_device(struct usb_device *dev);
extern void usbfs_remove_device(struct usb_device *dev);
extern void usbfs_update_special (void);
extern int usbfs_init(void);
extern void usbfs_cleanup(void);
#else /* CONFIG_USB_DEVICEFS */
static inline void usbfs_add_bus(struct usb_bus *bus) {}
static inline void usbfs_remove_bus(struct usb_bus *bus) {}
static inline void usbfs_add_device(struct usb_device *dev) {}
static inline void usbfs_remove_device(struct usb_device *dev) {}
static inline void usbfs_update_special (void) {}
static inline int usbfs_init(void) { return 0; }
static inline void usbfs_cleanup(void) { }
#endif /* CONFIG_USB_DEVICEFS */
/*-------------------------------------------------------------------------*/
/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
// bleech -- resurfaced in 2.4.11 or 2.4.12
#define bitmap DeviceRemovable
/*-------------------------------------------------------------------------*/
/* random stuff */
#define RUN_CONTEXT (in_irq () ? "in_irq" \
: (in_interrupt () ? "in_interrupt" : "can sleep"))
#endif /* __KERNEL__ */

File diff suppressed because it is too large Load diff

View file

@ -1,195 +0,0 @@
#ifndef __LINUX_HUB_H
#define __LINUX_HUB_H
/*
* Hub protocol and driver data structures.
*
* Some of these are known to the "virtual root hub" code
* in host controller drivers.
*/
#if 0
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/compiler.h> /* likely()/unlikely() */
#endif
/*
* Hub request types
*/
#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
/*
* Hub class requests
* See USB 2.0 spec Table 11-16
*/
#define HUB_CLEAR_TT_BUFFER 8
#define HUB_RESET_TT 9
#define HUB_GET_TT_STATE 10
#define HUB_STOP_TT 11
/*
* Hub Class feature numbers
* See USB 2.0 spec Table 11-17
*/
#define C_HUB_LOCAL_POWER 0
#define C_HUB_OVER_CURRENT 1
/*
* Port feature numbers
* See USB 2.0 spec Table 11-17
*/
#define USB_PORT_FEAT_CONNECTION 0
#define USB_PORT_FEAT_ENABLE 1
#define USB_PORT_FEAT_SUSPEND 2
#define USB_PORT_FEAT_OVER_CURRENT 3
#define USB_PORT_FEAT_RESET 4
#define USB_PORT_FEAT_POWER 8
#define USB_PORT_FEAT_LOWSPEED 9
#define USB_PORT_FEAT_HIGHSPEED 10
#define USB_PORT_FEAT_C_CONNECTION 16
#define USB_PORT_FEAT_C_ENABLE 17
#define USB_PORT_FEAT_C_SUSPEND 18
#define USB_PORT_FEAT_C_OVER_CURRENT 19
#define USB_PORT_FEAT_C_RESET 20
#define USB_PORT_FEAT_TEST 21
#define USB_PORT_FEAT_INDICATOR 22
/*
* Hub Status and Hub Change results
* See USB 2.0 spec Table 11-19 and Table 11-20
*/
struct usb_port_status {
__u16 wPortStatus;
__u16 wPortChange;
} __attribute__ ((packed));
/*
* wPortStatus bit field
* See USB 2.0 spec Table 11-21
*/
#define USB_PORT_STAT_CONNECTION 0x0001
#define USB_PORT_STAT_ENABLE 0x0002
#define USB_PORT_STAT_SUSPEND 0x0004
#define USB_PORT_STAT_OVERCURRENT 0x0008
#define USB_PORT_STAT_RESET 0x0010
/* bits 5 to 7 are reserved */
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
#define USB_PORT_STAT_HIGH_SPEED 0x0400
#define USB_PORT_STAT_TEST 0x0800
#define USB_PORT_STAT_INDICATOR 0x1000
/* bits 13 to 15 are reserved */
/*
* wPortChange bit field
* See USB 2.0 spec Table 11-22
* Bits 0 to 4 shown, bits 5 to 15 are reserved
*/
#define USB_PORT_STAT_C_CONNECTION 0x0001
#define USB_PORT_STAT_C_ENABLE 0x0002
#define USB_PORT_STAT_C_SUSPEND 0x0004
#define USB_PORT_STAT_C_OVERCURRENT 0x0008
#define USB_PORT_STAT_C_RESET 0x0010
/*
* wHubCharacteristics (masks)
* See USB 2.0 spec Table 11-13, offset 3
*/
#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
#define HUB_CHAR_COMPOUND 0x0004 /* D2 */
#define HUB_CHAR_OCPM 0x0018 /* D4 .. D3 */
#define HUB_CHAR_TTTT 0x0060 /* D6 .. D5 */
#define HUB_CHAR_PORTIND 0x0080 /* D7 */
struct usb_hub_status {
__u16 wHubStatus;
__u16 wHubChange;
} __attribute__ ((packed));
/*
* Hub Status & Hub Change bit masks
* See USB 2.0 spec Table 11-19 and Table 11-20
* Bits 0 and 1 for wHubStatus and wHubChange
* Bits 2 to 15 are reserved for both
*/
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
/*
* Hub descriptor
* See USB 2.0 spec Table 11-13
*/
#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
#define USB_DT_HUB_NONVAR_SIZE 7
struct usb_hub_descriptor {
__u8 bDescLength;
__u8 bDescriptorType;
__u8 bNbrPorts;
__u16 wHubCharacteristics;
__u8 bPwrOn2PwrGood;
__u8 bHubContrCurrent;
/* add 1 bit for hub status change; round to bytes */
__u8 DeviceRemovable[(USB_MAXCHILDREN + 1 + 7) / 8];
__u8 PortPwrCtrlMask[(USB_MAXCHILDREN + 1 + 7) / 8];
} __attribute__ ((packed));
struct usb_device;
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
* The other type grows from high speed hubs when they connect to
* full/low speed devices using "Transaction Translators" (TTs).
*
* TTs should only be known to the hub driver, and high speed bus
* drivers (only EHCI for now). They affect periodic scheduling and
* sometimes control/bulk error recovery.
*/
struct usb_tt {
struct usb_device *hub; /* upstream highspeed hub */
int multi; /* true means one TT per port */
/* for control/bulk error recovery (CLEAR_TT_BUFFER) */
spinlock_t lock;
struct list_head clear_list; /* of usb_tt_clear */
struct work_struct kevent;
};
struct usb_tt_clear {
struct list_head clear_list;
unsigned tt;
u16 devinfo;
};
extern void usb_hub_tt_clear_buffer (struct usb_device *dev, int pipe);
struct usb_hub {
struct usb_interface *intf; /* the "real" device */
struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... 1 bit each for hub and children, rounded up */
char (*buffer)[(USB_MAXCHILDREN + 1 + 7) / 8];
dma_addr_t buffer_dma; /* DMA address for buffer */
union {
struct usb_hub_status hub;
struct usb_port_status port;
} *status; /* buffer for status reports */
int error; /* last reported error */
int nerrors; /* track consecutive errors */
struct list_head hub_list; /* all hubs */
struct list_head event_list; /* hubs w/data or errs ready */
struct usb_hub_descriptor *descriptor; /* class descriptor */
struct semaphore khubd_sem;
struct usb_tt tt; /* Transaction Translator */
};
#endif /* __LINUX_HUB_H */

File diff suppressed because it is too large Load diff

View file

@ -1,423 +0,0 @@
#if 0
#include <linux/config.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/init.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
#include "hcd.h"
#else
#include "../usb_wrapper.h"
#include "hcd.h"
#endif
/**
* usb_init_urb - initializes a urb so that it can be used by a USB driver
* @urb: pointer to the urb to initialize
*
* Initializes a urb so that the USB subsystem can use it properly.
*
* If a urb is created with a call to usb_alloc_urb() it is not
* necessary to call this function. Only use this if you allocate the
* space for a struct urb on your own. If you call this function, be
* careful when freeing the memory for your urb that it is no longer in
* use by the USB core.
*
* Only use this function if you _really_ understand what you are doing.
*/
void usb_init_urb(struct urb *urb)
{
if (urb) {
memset(urb, 0, sizeof(*urb));
urb->count = (atomic_t)ATOMIC_INIT(1);
spin_lock_init(&urb->lock);
}
}
/**
* usb_alloc_urb - creates a new urb for a USB driver to use
* @iso_packets: number of iso packets for this urb
* @mem_flags: the type of memory to allocate, see kmalloc() for a list of
* valid options for this.
*
* Creates an urb for the USB driver to use, initializes a few internal
* structures, incrementes the usage counter, and returns a pointer to it.
*
* If no memory is available, NULL is returned.
*
* If the driver want to use this urb for interrupt, control, or bulk
* endpoints, pass '0' as the number of iso packets.
*
* The driver must call usb_free_urb() when it is finished with the urb.
*/
struct urb *usb_alloc_urb(int iso_packets, int mem_flags)
{
struct urb *urb;
urb = (struct urb *)kmalloc(sizeof(struct urb) +
iso_packets * sizeof(struct usb_iso_packet_descriptor),
mem_flags);
if (!urb) {
err("alloc_urb: kmalloc failed");
return NULL;
}
usb_init_urb(urb);
return urb;
}
/**
* usb_free_urb - frees the memory used by a urb when all users of it are finished
* @urb: pointer to the urb to free
*
* Must be called when a user of a urb is finished with it. When the last user
* of the urb calls this function, the memory of the urb is freed.
*
* Note: The transfer buffer associated with the urb is not freed, that must be
* done elsewhere.
*/
void usb_free_urb(struct urb *urb)
{
if (urb)
if (atomic_dec_and_test(&urb->count))
{
kfree(urb);
}
}
/**
* usb_get_urb - increments the reference count of the urb
* @urb: pointer to the urb to modify
*
* This must be called whenever a urb is transferred from a device driver to a
* host controller driver. This allows proper reference counting to happen
* for urbs.
*
* A pointer to the urb with the incremented reference counter is returned.
*/
struct urb * usb_get_urb(struct urb *urb)
{
if (urb) {
atomic_inc(&urb->count);
return urb;
} else
return NULL;
}
/*-------------------------------------------------------------------*/
/**
* usb_submit_urb - issue an asynchronous transfer request for an endpoint
* @urb: pointer to the urb describing the request
* @mem_flags: the type of memory to allocate, see kmalloc() for a list
* of valid options for this.
*
* This submits a transfer request, and transfers control of the URB
* describing that request to the USB subsystem. Request completion will
* be indicated later, asynchronously, by calling the completion handler.
* The three types of completion are success, error, and unlink
* (also called "request cancellation").
* URBs may be submitted in interrupt context.
*
* The caller must have correctly initialized the URB before submitting
* it. Functions such as usb_fill_bulk_urb() and usb_fill_control_urb() are
* available to ensure that most fields are correctly initialized, for
* the particular kind of transfer, although they will not initialize
* any transfer flags.
*
* Successful submissions return 0; otherwise this routine returns a
* negative error number. If the submission is successful, the complete()
* callback from the urb will be called exactly once, when the USB core and
* host controller driver are finished with the urb. When the completion
* function is called, control of the URB is returned to the device
* driver which issued the request. The completion handler may then
* immediately free or reuse that URB.
*
* For control endpoints, the synchronous usb_control_msg() call is
* often used (in non-interrupt context) instead of this call.
* That is often used through convenience wrappers, for the requests
* that are standardized in the USB 2.0 specification. For bulk
* endpoints, a synchronous usb_bulk_msg() call is available.
*
* Request Queuing:
*
* URBs may be submitted to endpoints before previous ones complete, to
* minimize the impact of interrupt latencies and system overhead on data
* throughput. This is required for continuous isochronous data streams,
* and may also be required for some kinds of interrupt transfers. Such
* queueing also maximizes bandwidth utilization by letting USB controllers
* start work on later requests before driver software has finished the
* completion processing for earlier requests.
*
* Bulk and Isochronous URBs may always be queued. At this writing, all
* mainstream host controller drivers support queueing for control and
* interrupt transfer requests.
*
* Reserved Bandwidth Transfers:
*
* Periodic transfers (interrupt or isochronous) are performed repeatedly,
* using the interval specified in the urb. Submitting the first urb to
* the endpoint reserves the bandwidth necessary to make those transfers.
* If the USB subsystem can't allocate sufficient bandwidth to perform
* the periodic request, submitting such a periodic request should fail.
*
* Device drivers must explicitly request that repetition, by ensuring that
* some URB is always on the endpoint's queue (except possibly for short
* periods during completion callacks). When there is no longer an urb
* queued, the endpoint's bandwidth reservation is canceled. This means
* drivers can use their completion handlers to ensure they keep bandwidth
* they need, by reinitializing and resubmitting the just-completed urb
* until the driver longer needs that periodic bandwidth.
*
* Memory Flags:
*
* The general rules for how to decide which mem_flags to use
* are the same as for kmalloc. There are four
* different possible values; GFP_KERNEL, GFP_NOFS, GFP_NOIO and
* GFP_ATOMIC.
*
* GFP_NOFS is not ever used, as it has not been implemented yet.
*
* GFP_ATOMIC is used when
* (a) you are inside a completion handler, an interrupt, bottom half,
* tasklet or timer, or
* (b) you are holding a spinlock or rwlock (does not apply to
* semaphores), or
* (c) current->state != TASK_RUNNING, this is the case only after
* you've changed it.
*
* GFP_NOIO is used in the block io path and error handling of storage
* devices.
*
* All other situations use GFP_KERNEL.
*
* Some more specific rules for mem_flags can be inferred, such as
* (1) start_xmit, timeout, and receive methods of network drivers must
* use GFP_ATOMIC (they are called with a spinlock held);
* (2) queuecommand methods of scsi drivers must use GFP_ATOMIC (also
* called with a spinlock held);
* (3) If you use a kernel thread with a network driver you must use
* GFP_NOIO, unless (b) or (c) apply;
* (4) after you have done a down() you can use GFP_KERNEL, unless (b) or (c)
* apply or your are in a storage driver's block io path;
* (5) USB probe and disconnect can use GFP_KERNEL unless (b) or (c) apply; and
* (6) changing firmware on a running storage or net device uses
* GFP_NOIO, unless b) or c) apply
*
*/
int usb_submit_urb(struct urb *urb, int mem_flags)
{
int pipe, temp, max;
struct usb_device *dev;
struct usb_operations *op;
int is_out;
// printk("sub dev %p bus %p num %i op %p sub %p\n",
// urb->dev, urb->dev->bus,urb->dev->devnum,urb->dev->bus->op, urb->dev->bus->op->submit_urb);
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
if (!(dev = urb->dev) ||
(dev->state < USB_STATE_DEFAULT) ||
(!dev->bus) || (dev->devnum <= 0))
return -ENODEV;
if (!(op = dev->bus->op) || !op->submit_urb)
return -ENODEV;
urb->status = -EINPROGRESS;
urb->actual_length = 0;
urb->bandwidth = 0;
/* Lots of sanity checks, so HCDs can rely on clean data
* and don't need to duplicate tests
*/
pipe = urb->pipe;
temp = usb_pipetype (pipe);
is_out = usb_pipeout (pipe);
if (!usb_pipecontrol (pipe) && dev->state < USB_STATE_CONFIGURED)
return -ENODEV;
/* (actually HCDs may need to duplicate this, endpoint might yet
* stall due to queued bulk/intr transactions that complete after
* we check)
*/
if (usb_endpoint_halted (dev, usb_pipeendpoint (pipe), is_out))
return -EPIPE;
/* FIXME there should be a sharable lock protecting us against
* config/altsetting changes and disconnects, kicking in here.
* (here == before maxpacket, and eventually endpoint type,
* checks get made.)
*/
max = usb_maxpacket (dev, pipe, is_out);
if (max <= 0) {
dbg ("%s: bogus endpoint %d-%s on usb-%s-%s (bad maxpacket %d)",
__FUNCTION__,
usb_pipeendpoint (pipe), is_out ? "OUT" : "IN",
dev->bus->bus_name, dev->devpath,
max);
return -EMSGSIZE;
}
/* periodic transfers limit size per frame/uframe,
* but drivers only control those sizes for ISO.
* while we're checking, initialize return status.
*/
if (temp == PIPE_ISOCHRONOUS) {
int n, len;
/* "high bandwidth" mode, 1-3 packets/uframe? */
if (dev->speed == USB_SPEED_HIGH) {
int mult = 1 + ((max >> 11) & 0x03);
max &= 0x03ff;
max *= mult;
}
if (urb->number_of_packets <= 0)
return -EINVAL;
for (n = 0; n < urb->number_of_packets; n++) {
len = urb->iso_frame_desc [n].length;
if (len < 0 || len > max)
return -EMSGSIZE;
urb->iso_frame_desc [n].status = -EXDEV;
urb->iso_frame_desc [n].actual_length = 0;
}
}
/* the I/O buffer must be mapped/unmapped, except when length=0 */
if (urb->transfer_buffer_length < 0)
return -EMSGSIZE;
#ifdef DEBUG
/* stuff that drivers shouldn't do, but which shouldn't
* cause problems in HCDs if they get it wrong.
*/
{
unsigned int orig_flags = urb->transfer_flags;
unsigned int allowed;
/* enforce simple/standard policy */
allowed = URB_ASYNC_UNLINK; // affects later unlinks
allowed |= URB_NO_DMA_MAP;
allowed |= URB_NO_INTERRUPT;
switch (temp) {
case PIPE_BULK:
if (is_out)
allowed |= URB_ZERO_PACKET;
/* FALLTHROUGH */
case PIPE_CONTROL:
allowed |= URB_NO_FSBR; /* only affects UHCI */
/* FALLTHROUGH */
default: /* all non-iso endpoints */
if (!is_out)
allowed |= URB_SHORT_NOT_OK;
break;
case PIPE_ISOCHRONOUS:
allowed |= URB_ISO_ASAP;
break;
}
urb->transfer_flags &= allowed;
/* fail if submitter gave bogus flags */
if (urb->transfer_flags != orig_flags) {
err ("BOGUS urb flags, %x --> %x",
orig_flags, urb->transfer_flags);
return -EINVAL;
}
}
#endif
/*
* Force periodic transfer intervals to be legal values that are
* a power of two (so HCDs don't need to).
*
* FIXME want bus->{intr,iso}_sched_horizon values here. Each HC
* supports different values... this uses EHCI/UHCI defaults (and
* EHCI can use smaller non-default values).
*/
switch (temp) {
case PIPE_ISOCHRONOUS:
case PIPE_INTERRUPT:
/* too small? */
if (urb->interval <= 0)
return -EINVAL;
/* too big? */
switch (dev->speed) {
case USB_SPEED_HIGH: /* units are microframes */
// NOTE usb handles 2^15
if (urb->interval > (1024 * 8))
urb->interval = 1024 * 8;
temp = 1024 * 8;
break;
case USB_SPEED_FULL: /* units are frames/msec */
case USB_SPEED_LOW:
if (temp == PIPE_INTERRUPT) {
if (urb->interval > 255)
return -EINVAL;
// NOTE ohci only handles up to 32
temp = 128;
} else {
if (urb->interval > 1024)
urb->interval = 1024;
// NOTE usb and ohci handle up to 2^15
temp = 1024;
}
break;
default:
return -EINVAL;
}
/* power of two? */
while (temp > urb->interval)
temp >>= 1;
urb->interval = temp;
}
return op->submit_urb (urb, mem_flags);
}
/*-------------------------------------------------------------------*/
/**
* usb_unlink_urb - abort/cancel a transfer request for an endpoint
* @urb: pointer to urb describing a previously submitted request
*
* This routine cancels an in-progress request. The requests's
* completion handler will be called with a status code indicating
* that the request has been canceled, and that control of the URB
* has been returned to that device driver.
*
* When the URB_ASYNC_UNLINK transfer flag for the URB is clear, this
* request is synchronous. Success is indicated by returning zero,
* at which time the urb will have been unlinked,
* and the completion function will see status -ENOENT. Failure is
* indicated by any other return value. This mode may not be used
* when unlinking an urb from an interrupt context, such as a bottom
* half or a completion handler,
*
* When the URB_ASYNC_UNLINK transfer flag for the URB is set, this
* request is asynchronous. Success is indicated by returning -EINPROGRESS,
* at which time the urb will normally not have been unlinked,
* and the completion function will see status -ECONNRESET. Failure is
* indicated by any other return value.
*/
int usb_unlink_urb(struct urb *urb)
{
if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
return urb->dev->bus->op->unlink_urb(urb);
else
return -ENODEV;
}
EXPORT_SYMBOL(usb_init_urb);
EXPORT_SYMBOL(usb_alloc_urb);
EXPORT_SYMBOL(usb_free_urb);
EXPORT_SYMBOL(usb_get_urb);
EXPORT_SYMBOL(usb_submit_urb);
EXPORT_SYMBOL(usb_unlink_urb);

View file

@ -1,206 +0,0 @@
/*
* debug.c - USB debug helper routines.
*
* I just want these out of the way where they aren't in your
* face, but so that you can still use them..
*/
#define CONFIG_USB_DEBUG
#if 0
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#ifdef CONFIG_USB_DEBUG
#define DEBUG
#else
#undef DEBUG
#endif
#include <linux/usb.h>
#else
#include "../usb_wrapper.h"
#endif
static void usb_show_endpoint(struct usb_host_endpoint *endpoint)
{
usb_show_endpoint_descriptor(&endpoint->desc);
}
static void usb_show_interface(struct usb_host_interface *altsetting)
{
int i;
usb_show_interface_descriptor(&altsetting->desc);
for (i = 0; i < altsetting->desc.bNumEndpoints; i++)
usb_show_endpoint(altsetting->endpoint + i);
}
static void usb_show_config(struct usb_host_config *config)
{
int i, j;
struct usb_interface *ifp;
usb_show_config_descriptor(&config->desc);
for (i = 0; i < config->desc.bNumInterfaces; i++) {
ifp = config->interface + i;
if (!ifp)
break;
printk("\n Interface: %d\n", i);
for (j = 0; j < ifp->num_altsetting; j++)
usb_show_interface(ifp->altsetting + j);
}
}
void usb_show_device(struct usb_device *dev)
{
int i;
usb_show_device_descriptor(&dev->descriptor);
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
usb_show_config(dev->config + i);
}
/*
* Parse and show the different USB descriptors.
*/
void usb_show_device_descriptor(struct usb_device_descriptor *desc)
{
if (!desc)
{
printk("Invalid USB device descriptor (NULL POINTER)\n");
return;
}
printk(" Length = %2d%s\n", desc->bLength,
desc->bLength == USB_DT_DEVICE_SIZE ? "" : " (!!!)");
printk(" DescriptorType = %02x\n", desc->bDescriptorType);
printk(" USB version = %x.%02x\n",
desc->bcdUSB >> 8, desc->bcdUSB & 0xff);
printk(" Vendor:Product = %04x:%04x\n",
desc->idVendor, desc->idProduct);
printk(" MaxPacketSize0 = %d\n", desc->bMaxPacketSize0);
printk(" NumConfigurations = %d\n", desc->bNumConfigurations);
printk(" Device version = %x.%02x\n",
desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
printk(" Device Class:SubClass:Protocol = %02x:%02x:%02x\n",
desc->bDeviceClass, desc->bDeviceSubClass, desc->bDeviceProtocol);
switch (desc->bDeviceClass) {
case 0:
printk(" Per-interface classes\n");
break;
case USB_CLASS_AUDIO:
printk(" Audio device class\n");
break;
case USB_CLASS_COMM:
printk(" Communications class\n");
break;
case USB_CLASS_HID:
printk(" Human Interface Devices class\n");
break;
case USB_CLASS_PRINTER:
printk(" Printer device class\n");
break;
case USB_CLASS_MASS_STORAGE:
printk(" Mass Storage device class\n");
break;
case USB_CLASS_HUB:
printk(" Hub device class\n");
break;
case USB_CLASS_VENDOR_SPEC:
printk(" Vendor class\n");
break;
default:
printk(" Unknown class\n");
}
}
void usb_show_config_descriptor(struct usb_config_descriptor *desc)
{
printk("Configuration:\n");
printk(" bLength = %4d%s\n", desc->bLength,
desc->bLength == USB_DT_CONFIG_SIZE ? "" : " (!!!)");
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" wTotalLength = %04x\n", desc->wTotalLength);
printk(" bNumInterfaces = %02x\n", desc->bNumInterfaces);
printk(" bConfigurationValue = %02x\n", desc->bConfigurationValue);
printk(" iConfiguration = %02x\n", desc->iConfiguration);
printk(" bmAttributes = %02x\n", desc->bmAttributes);
printk(" bMaxPower = %4dmA\n", desc->bMaxPower * 2);
}
void usb_show_interface_descriptor(struct usb_interface_descriptor *desc)
{
printk(" Alternate Setting: %2d\n", desc->bAlternateSetting);
printk(" bLength = %4d%s\n", desc->bLength,
desc->bLength == USB_DT_INTERFACE_SIZE ? "" : " (!!!)");
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" bInterfaceNumber = %02x\n", desc->bInterfaceNumber);
printk(" bAlternateSetting = %02x\n", desc->bAlternateSetting);
printk(" bNumEndpoints = %02x\n", desc->bNumEndpoints);
printk(" bInterface Class:SubClass:Protocol = %02x:%02x:%02x\n",
desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol);
printk(" iInterface = %02x\n", desc->iInterface);
}
void usb_show_endpoint_descriptor(struct usb_endpoint_descriptor *desc)
{
char *LengthCommentString = (desc->bLength ==
USB_DT_ENDPOINT_AUDIO_SIZE) ? " (Audio)" : (desc->bLength ==
USB_DT_ENDPOINT_SIZE) ? "" : " (!!!)";
char *EndpointType[4] = { "Control", "Isochronous", "Bulk", "Interrupt" };
printk(" Endpoint:\n");
printk(" bLength = %4d%s\n",
desc->bLength, LengthCommentString);
printk(" bDescriptorType = %02x\n", desc->bDescriptorType);
printk(" bEndpointAddress = %02x (%s)\n", desc->bEndpointAddress,
(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_CONTROL ? "i/o" :
(desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ? "in" : "out");
printk(" bmAttributes = %02x (%s)\n", desc->bmAttributes,
EndpointType[USB_ENDPOINT_XFERTYPE_MASK & desc->bmAttributes]);
printk(" wMaxPacketSize = %04x\n", desc->wMaxPacketSize);
printk(" bInterval = %02x\n", desc->bInterval);
/* Audio extensions to the endpoint descriptor */
if (desc->bLength == USB_DT_ENDPOINT_AUDIO_SIZE) {
printk(" bRefresh = %02x\n", desc->bRefresh);
printk(" bSynchAddress = %02x\n", desc->bSynchAddress);
}
}
void usb_show_string(struct usb_device *dev, char *id, int index)
{
char *buf;
if (!index)
return;
if (!(buf = kmalloc(256, GFP_KERNEL)))
return;
if (usb_string(dev, index, buf, 256) > 0)
dev_printk(KERN_INFO, &dev->dev, "%s: %s\n", id, buf);
kfree(buf);
}
void usb_dump_urb (struct urb *urb)
{
printk ("urb :%p\n", urb);
printk ("dev :%p\n", urb->dev);
printk ("pipe :%08X\n", urb->pipe);
printk ("status :%d\n", urb->status);
printk ("transfer_flags :%08X\n", urb->transfer_flags);
printk ("transfer_buffer :%p\n", urb->transfer_buffer);
printk ("transfer_buffer_length:%d\n", urb->transfer_buffer_length);
printk ("actual_length :%d\n", urb->actual_length);
printk ("setup_packet :%p\n", urb->setup_packet);
printk ("start_frame :%d\n", urb->start_frame);
printk ("number_of_packets :%d\n", urb->number_of_packets);
printk ("interval :%d\n", urb->interval);
printk ("error_count :%d\n", urb->error_count);
printk ("context :%p\n", urb->context);
printk ("complete :%p\n", urb->complete);
}

File diff suppressed because it is too large Load diff

View file

@ -1,5 +0,0 @@
/* Functions local to drivers/usb/core/ */
extern void usb_create_driverfs_dev_files (struct usb_device *dev);
extern void usb_create_driverfs_intf_files (struct usb_interface *intf);

View file

@ -1,3 +0,0 @@
O_TARGET := ohci-hcd.o
include $(TOPDIR)/Rules.make

View file

@ -1,666 +0,0 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
*/
/*-------------------------------------------------------------------------*/
#ifdef DEBUG
#define edstring(ed_type) ({ char *temp; \
switch (ed_type) { \
case PIPE_CONTROL: temp = "ctrl"; break; \
case PIPE_BULK: temp = "bulk"; break; \
case PIPE_INTERRUPT: temp = "intr"; break; \
default: temp = "isoc"; break; \
}; temp;})
#define pipestring(pipe) edstring(usb_pipetype(pipe))
/* debug| print the main components of an URB
* small: 0) header + data packets 1) just header
*/
static void __attribute__((unused))
urb_print (struct urb * urb, char * str, int small)
{
unsigned int pipe= urb->pipe;
if (!urb->dev || !urb->dev->bus) {
dbg("%s URB: no dev", str);
return;
}
#ifndef OHCI_VERBOSE_DEBUG
if (urb->status != 0)
#endif
dbg("%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d",
str,
urb,
usb_pipedevice (pipe),
usb_pipeendpoint (pipe),
usb_pipeout (pipe)? "out" : "in",
pipestring (pipe),
urb->transfer_flags,
urb->actual_length,
urb->transfer_buffer_length,
urb->status);
#ifdef OHCI_VERBOSE_DEBUG
if (!small) {
int i, len;
if (usb_pipecontrol (pipe)) {
printk (KERN_DEBUG __FILE__ ": setup(8):");
for (i = 0; i < 8 ; i++)
printk (" %02x", ((__u8 *) urb->setup_packet) [i]);
printk ("\n");
}
if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
printk (KERN_DEBUG __FILE__ ": data(%d/%d):",
urb->actual_length,
urb->transfer_buffer_length);
len = usb_pipeout (pipe)?
urb->transfer_buffer_length: urb->actual_length;
for (i = 0; i < 16 && i < len; i++)
printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]);
printk ("%s stat:%d\n", i < len? "...": "", urb->status);
}
}
#endif
}
#define ohci_dbg_sw(ohci, next, size, format, arg...) \
do { \
if (next) { \
unsigned s_len; \
s_len = snprintf (*next, *size, format, ## arg ); \
*size -= s_len; *next += s_len; \
} else \
ohci_dbg(ohci,format, ## arg ); \
} while (0);
static void ohci_dump_intr_mask (
struct ohci_hcd *ohci,
char *label,
u32 mask,
char **next,
unsigned *size)
{
ohci_dbg_sw (ohci, next, size, "%s 0x%08x%s%s%s%s%s%s%s%s%s\n",
label,
mask,
(mask & OHCI_INTR_MIE) ? " MIE" : "",
(mask & OHCI_INTR_OC) ? " OC" : "",
(mask & OHCI_INTR_RHSC) ? " RHSC" : "",
(mask & OHCI_INTR_FNO) ? " FNO" : "",
(mask & OHCI_INTR_UE) ? " UE" : "",
(mask & OHCI_INTR_RD) ? " RD" : "",
(mask & OHCI_INTR_SF) ? " SF" : "",
(mask & OHCI_INTR_WDH) ? " WDH" : "",
(mask & OHCI_INTR_SO) ? " SO" : ""
);
}
static void maybe_print_eds (
struct ohci_hcd *ohci,
char *label,
u32 value,
char **next,
unsigned *size)
{
if (value)
ohci_dbg_sw (ohci, next, size, "%s %08x\n", label, value);
}
static char *hcfs2string (int state)
{
switch (state) {
case OHCI_USB_RESET: return "reset";
case OHCI_USB_RESUME: return "resume";
case OHCI_USB_OPER: return "operational";
case OHCI_USB_SUSPEND: return "suspend";
}
return "?";
}
// dump control and status registers
static void
ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
{
struct ohci_regs *regs = controller->regs;
u32 temp;
temp = readl (&regs->revision) & 0xff;
ohci_dbg_sw (controller, next, size,
"OHCI %d.%d, %s legacy support registers\n",
0x03 & (temp >> 4), (temp & 0x0f),
(temp & 0x10) ? "with" : "NO");
temp = readl (&regs->control);
ohci_dbg_sw (controller, next, size,
"control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n",
temp,
(temp & OHCI_CTRL_RWE) ? " RWE" : "",
(temp & OHCI_CTRL_RWC) ? " RWC" : "",
(temp & OHCI_CTRL_IR) ? " IR" : "",
hcfs2string (temp & OHCI_CTRL_HCFS),
(temp & OHCI_CTRL_BLE) ? " BLE" : "",
(temp & OHCI_CTRL_CLE) ? " CLE" : "",
(temp & OHCI_CTRL_IE) ? " IE" : "",
(temp & OHCI_CTRL_PLE) ? " PLE" : "",
temp & OHCI_CTRL_CBSR
);
temp = readl (&regs->cmdstatus);
ohci_dbg_sw (controller, next, size,
"cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp,
(temp & OHCI_SOC) >> 16,
(temp & OHCI_OCR) ? " OCR" : "",
(temp & OHCI_BLF) ? " BLF" : "",
(temp & OHCI_CLF) ? " CLF" : "",
(temp & OHCI_HCR) ? " HCR" : ""
);
ohci_dump_intr_mask (controller, "intrstatus",
readl (&regs->intrstatus), next, size);
ohci_dump_intr_mask (controller, "intrenable",
readl (&regs->intrenable), next, size);
// intrdisable always same as intrenable
maybe_print_eds (controller, "ed_periodcurrent",
readl (&regs->ed_periodcurrent), next, size);
maybe_print_eds (controller, "ed_controlhead",
readl (&regs->ed_controlhead), next, size);
maybe_print_eds (controller, "ed_controlcurrent",
readl (&regs->ed_controlcurrent), next, size);
maybe_print_eds (controller, "ed_bulkhead",
readl (&regs->ed_bulkhead), next, size);
maybe_print_eds (controller, "ed_bulkcurrent",
readl (&regs->ed_bulkcurrent), next, size);
maybe_print_eds (controller, "donehead",
readl (&regs->donehead), next, size);
}
#define dbg_port_sw(hc,num,value,next,size) \
ohci_dbg_sw (hc, next, size, \
"roothub.portstatus [%d] " \
"0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
num, temp, \
(temp & RH_PS_PRSC) ? " PRSC" : "", \
(temp & RH_PS_OCIC) ? " OCIC" : "", \
(temp & RH_PS_PSSC) ? " PSSC" : "", \
(temp & RH_PS_PESC) ? " PESC" : "", \
(temp & RH_PS_CSC) ? " CSC" : "", \
\
(temp & RH_PS_LSDA) ? " LSDA" : "", \
(temp & RH_PS_PPS) ? " PPS" : "", \
(temp & RH_PS_PRS) ? " PRS" : "", \
(temp & RH_PS_POCI) ? " POCI" : "", \
(temp & RH_PS_PSS) ? " PSS" : "", \
\
(temp & RH_PS_PES) ? " PES" : "", \
(temp & RH_PS_CCS) ? " CCS" : "" \
);
static void
ohci_dump_roothub (
struct ohci_hcd *controller,
int verbose,
char **next,
unsigned *size)
{
u32 temp, ndp, i;
temp = roothub_a (controller);
if (temp == ~(u32)0)
return;
ndp = (temp & RH_A_NDP);
if (verbose) {
ohci_dbg_sw (controller, next, size,
"roothub.a %08x POTPGT=%d%s%s%s%s%s NDP=%d\n", temp,
((temp & RH_A_POTPGT) >> 24) & 0xff,
(temp & RH_A_NOCP) ? " NOCP" : "",
(temp & RH_A_OCPM) ? " OCPM" : "",
(temp & RH_A_DT) ? " DT" : "",
(temp & RH_A_NPS) ? " NPS" : "",
(temp & RH_A_PSM) ? " PSM" : "",
ndp
);
temp = roothub_b (controller);
ohci_dbg_sw (controller, next, size,
"roothub.b %08x PPCM=%04x DR=%04x\n",
temp,
(temp & RH_B_PPCM) >> 16,
(temp & RH_B_DR)
);
temp = roothub_status (controller);
ohci_dbg_sw (controller, next, size,
"roothub.status %08x%s%s%s%s%s%s\n",
temp,
(temp & RH_HS_CRWE) ? " CRWE" : "",
(temp & RH_HS_OCIC) ? " OCIC" : "",
(temp & RH_HS_LPSC) ? " LPSC" : "",
(temp & RH_HS_DRWE) ? " DRWE" : "",
(temp & RH_HS_OCI) ? " OCI" : "",
(temp & RH_HS_LPS) ? " LPS" : ""
);
}
for (i = 0; i < ndp; i++) {
temp = roothub_portstatus (controller, i);
dbg_port_sw (controller, i, temp, next, size);
}
}
static void ohci_dump (struct ohci_hcd *controller, int verbose)
{
ohci_dbg (controller, "OHCI controller state\n");
// dumps some of the state we know about
ohci_dump_status (controller, NULL, 0);
if (controller->hcca)
ohci_dbg (controller,
"hcca frame #%04x\n", controller->hcca->frame_no);
ohci_dump_roothub (controller, 1, NULL, 0);
}
static const char data0 [] = "DATA0";
static const char data1 [] = "DATA1";
static void ohci_dump_td (struct ohci_hcd *ohci, char *label, struct td *td)
{
u32 tmp = le32_to_cpup (&td->hwINFO);
ohci_dbg (ohci, "%s td %p%s; urb %p index %d; hw next td %08x",
label, td,
(tmp & TD_DONE) ? " (DONE)" : "",
td->urb, td->index,
le32_to_cpup (&td->hwNextTD));
if ((tmp & TD_ISO) == 0) {
const char *toggle, *pid;
u32 cbp, be;
switch (tmp & TD_T) {
case TD_T_DATA0: toggle = data0; break;
case TD_T_DATA1: toggle = data1; break;
case TD_T_TOGGLE: toggle = "(CARRY)"; break;
default: toggle = "(?)"; break;
}
switch (tmp & TD_DP) {
case TD_DP_SETUP: pid = "SETUP"; break;
case TD_DP_IN: pid = "IN"; break;
case TD_DP_OUT: pid = "OUT"; break;
default: pid = "(bad pid)"; break;
}
ohci_dbg (ohci, " info %08x CC=%x %s DI=%d %s %s", tmp,
TD_CC_GET(tmp), /* EC, */ toggle,
(tmp & TD_DI) >> 21, pid,
(tmp & TD_R) ? "R" : "");
cbp = le32_to_cpup (&td->hwCBP);
be = le32_to_cpup (&td->hwBE);
ohci_dbg (ohci, " cbp %08x be %08x (len %d)", cbp, be,
cbp ? (be + 1 - cbp) : 0);
} else {
unsigned i;
ohci_dbg (ohci, " info %08x CC=%x FC=%d DI=%d SF=%04x", tmp,
TD_CC_GET(tmp),
(tmp >> 24) & 0x07,
(tmp & TD_DI) >> 21,
tmp & 0x0000ffff);
ohci_dbg (ohci, " bp0 %08x be %08x",
le32_to_cpup (&td->hwCBP) & ~0x0fff,
le32_to_cpup (&td->hwBE));
for (i = 0; i < MAXPSW; i++) {
u16 psw = le16_to_cpup (&td->hwPSW [i]);
int cc = (psw >> 12) & 0x0f;
ohci_dbg (ohci, " psw [%d] = %2x, CC=%x %s=%d", i,
psw, cc,
(cc >= 0x0e) ? "OFFSET" : "SIZE",
psw & 0x0fff);
}
}
}
/* caller MUST own hcd spinlock if verbose is set! */
static void __attribute__((unused))
ohci_dump_ed (struct ohci_hcd *ohci, char *label, struct ed *ed, int verbose)
{
u32 tmp = ed->hwINFO;
char *type = "";
ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x",
label,
ed, ed->state, edstring (ed->type),
le32_to_cpup (&ed->hwNextED));
switch (tmp & (ED_IN|ED_OUT)) {
case ED_OUT: type = "-OUT"; break;
case ED_IN: type = "-IN"; break;
/* else from TDs ... control */
}
ohci_dbg (ohci,
" info %08x MAX=%d%s%s%s%s EP=%d%s DEV=%d", le32_to_cpu (tmp),
0x03ff & (le32_to_cpu (tmp) >> 16),
(tmp & ED_DEQUEUE) ? " DQ" : "",
(tmp & ED_ISO) ? " ISO" : "",
(tmp & ED_SKIP) ? " SKIP" : "",
(tmp & ED_LOWSPEED) ? " LOW" : "",
0x000f & (le32_to_cpu (tmp) >> 7),
type,
0x007f & le32_to_cpu (tmp));
ohci_dbg (ohci, " tds: head %08x %s%s tail %08x%s",
tmp = le32_to_cpup (&ed->hwHeadP),
(ed->hwHeadP & ED_C) ? data1 : data0,
(ed->hwHeadP & ED_H) ? " HALT" : "",
le32_to_cpup (&ed->hwTailP),
verbose ? "" : " (not listing)");
if (verbose) {
struct list_head *tmp;
/* use ed->td_list because HC concurrently modifies
* hwNextTD as it accumulates ed_donelist.
*/
list_for_each (tmp, &ed->td_list) {
struct td *td;
td = list_entry (tmp, struct td, td_list);
ohci_dump_td (ohci, " ->", td);
}
}
}
#else
static inline void ohci_dump (struct ohci_hcd *controller, int verbose) {}
#undef OHCI_VERBOSE_DEBUG
#endif /* DEBUG */
/*-------------------------------------------------------------------------*/
#ifdef STUB_DEBUG_FILES
static inline void create_debug_files (struct ohci_hcd *bus) { }
static inline void remove_debug_files (struct ohci_hcd *bus) { }
#else
static inline struct ohci_hcd *dev_to_ohci (struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata (dev);
return hcd_to_ohci (hcd);
}
static ssize_t
show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
{
unsigned temp, size = count;
if (!ed)
return 0;
/* print first --> last */
while (ed->ed_prev)
ed = ed->ed_prev;
/* dump a snapshot of the bulk or control schedule */
while (ed) {
u32 info = ed->hwINFO;
u32 scratch = cpu_to_le32p (&ed->hwINFO);
struct list_head *entry;
struct td *td;
temp = snprintf (buf, size,
"ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s",
ed,
(info & ED_LOWSPEED) ? 'l' : 'f',
scratch & 0x7f,
(scratch >> 7) & 0xf,
(info & ED_IN) ? "in" : "out",
0x03ff & (scratch >> 16),
scratch,
(info & ED_SKIP) ? " s" : "",
(ed->hwHeadP & ED_H) ? " H" : "",
(ed->hwHeadP & ED_C) ? data1 : data0);
size -= temp;
buf += temp;
list_for_each (entry, &ed->td_list) {
u32 cbp, be;
td = list_entry (entry, struct td, td_list);
scratch = cpu_to_le32p (&td->hwINFO);
cbp = le32_to_cpup (&td->hwCBP);
be = le32_to_cpup (&td->hwBE);
temp = snprintf (buf, size,
"\n\ttd %p %s %d cc=%x urb %p (%08x)",
td,
({ char *pid;
switch (scratch & TD_DP) {
case TD_DP_SETUP: pid = "setup"; break;
case TD_DP_IN: pid = "in"; break;
case TD_DP_OUT: pid = "out"; break;
default: pid = "(?)"; break;
} pid;}),
cbp ? (be + 1 - cbp) : 0,
TD_CC_GET (scratch), td->urb, scratch);
size -= temp;
buf += temp;
}
temp = snprintf (buf, size, "\n");
size -= temp;
buf += temp;
ed = ed->ed_next;
}
return count - size;
}
static ssize_t
show_async (struct device *dev, char *buf)
{
struct ohci_hcd *ohci;
size_t temp;
unsigned long flags;
ohci = dev_to_ohci(dev);
/* display control and bulk lists together, for simplicity */
spin_lock_irqsave (&ohci->lock, flags);
temp = show_list (ohci, buf, PAGE_SIZE, ohci->ed_controltail);
temp += show_list (ohci, buf + temp, PAGE_SIZE - temp, ohci->ed_bulktail);
spin_unlock_irqrestore (&ohci->lock, flags);
return temp;
}
static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
#define DBG_SCHED_LIMIT 64
static ssize_t
show_periodic (struct device *dev, char *buf)
{
struct ohci_hcd *ohci;
struct ed **seen, *ed;
unsigned long flags;
unsigned temp, size, seen_count;
char *next;
unsigned i;
if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
return 0;
seen_count = 0;
ohci = dev_to_ohci(dev);
next = buf;
size = PAGE_SIZE;
temp = snprintf (next, size, "size = %d\n", NUM_INTS);
size -= temp;
next += temp;
/* dump a snapshot of the periodic schedule (and load) */
spin_lock_irqsave (&ohci->lock, flags);
for (i = 0; i < NUM_INTS; i++) {
if (!(ed = ohci->periodic [i]))
continue;
temp = snprintf (next, size, "%2d [%3d]:", i, ohci->load [i]);
size -= temp;
next += temp;
do {
temp = snprintf (next, size, " ed%d/%p",
ed->interval, ed);
size -= temp;
next += temp;
for (temp = 0; temp < seen_count; temp++) {
if (seen [temp] == ed)
break;
}
/* show more info the first time around */
if (temp == seen_count) {
u32 info = ed->hwINFO;
u32 scratch = cpu_to_le32p (&ed->hwINFO);
temp = snprintf (next, size,
" (%cs dev%d%s ep%d%s"
" max %d %08x%s%s)",
(info & ED_LOWSPEED) ? 'l' : 'f',
scratch & 0x7f,
(info & ED_ISO) ? " iso" : "",
(scratch >> 7) & 0xf,
(info & ED_IN) ? "in" : "out",
0x03ff & (scratch >> 16),
scratch,
(info & ED_SKIP) ? " s" : "",
(ed->hwHeadP & ED_H) ? " H" : "");
size -= temp;
next += temp;
// FIXME some TD info too
if (seen_count < DBG_SCHED_LIMIT)
seen [seen_count++] = ed;
ed = ed->ed_next;
} else {
/* we've seen it and what's after */
temp = 0;
ed = 0;
}
} while (ed);
temp = snprintf (next, size, "\n");
size -= temp;
next += temp;
}
spin_unlock_irqrestore (&ohci->lock, flags);
kfree (seen);
return PAGE_SIZE - size;
}
static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
#undef DBG_SCHED_LIMIT
static ssize_t
show_registers (struct device *dev, char *buf)
{
struct ohci_hcd *ohci;
struct ohci_regs *regs;
unsigned long flags;
unsigned temp, size;
char *next;
u32 rdata;
ohci = dev_to_ohci(dev);
regs = ohci->regs;
next = buf;
size = PAGE_SIZE;
spin_lock_irqsave (&ohci->lock, flags);
/* dump driver info, then registers in spec order */
ohci_dbg_sw (ohci, &next, &size,
"%s version " DRIVER_VERSION "\n", hcd_name);
ohci_dump_status(ohci, &next, &size);
/* hcca */
if (ohci->hcca)
ohci_dbg_sw (ohci, &next, &size,
"hcca frame 0x%04x\n", ohci->hcca->frame_no);
/* other registers mostly affect frame timings */
rdata = readl (&regs->fminterval);
temp = snprintf (next, size,
"fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n",
rdata, (rdata >> 31) ? " FIT" : "",
(rdata >> 16) & 0xefff, rdata & 0xffff);
size -= temp;
next += temp;
rdata = readl (&regs->fmremaining);
temp = snprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n",
rdata, (rdata >> 31) ? " FRT" : "",
rdata & 0x3fff);
size -= temp;
next += temp;
rdata = readl (&regs->periodicstart);
temp = snprintf (next, size, "periodicstart 0x%04x\n",
rdata & 0x3fff);
size -= temp;
next += temp;
rdata = readl (&regs->lsthresh);
temp = snprintf (next, size, "lsthresh 0x%04x\n",
rdata & 0x3fff);
size -= temp;
next += temp;
/* roothub */
ohci_dump_roothub (ohci, 1, &next, &size);
spin_unlock_irqrestore (&ohci->lock, flags);
return PAGE_SIZE - size;
}
static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
static inline void create_debug_files (struct ohci_hcd *bus)
{
device_create_file (bus->hcd.controller, &dev_attr_async);
device_create_file (bus->hcd.controller, &dev_attr_periodic);
device_create_file (bus->hcd.controller, &dev_attr_registers);
ohci_dbg (bus, "created debug files\n");
}
static inline void remove_debug_files (struct ohci_hcd *bus)
{
device_remove_file (bus->hcd.controller, &dev_attr_async);
device_remove_file (bus->hcd.controller, &dev_attr_periodic);
device_remove_file (bus->hcd.controller, &dev_attr_registers);
}
#endif
/*-------------------------------------------------------------------------*/

View file

@ -1,705 +0,0 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* [ Initialisation is based on Linus' ]
* [ uhci code and gregs ohci fragments ]
* [ (C) Copyright 1999 Linus Torvalds ]
* [ (C) Copyright 1999 Gregory P. Smith]
*
*
* OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller
* interfaces (though some non-x86 Intel chips use it). It supports
* smarter hardware than UHCI. A download link for the spec available
* through the http://www.usb.org website.
*
* History:
*
* 2003/02/24 show registers in sysfs (Kevin Brosius)
*
* 2002/09/03 get rid of ed hashtables, rework periodic scheduling and
* bandwidth accounting; if debugging, show schedules in driverfs
* 2002/07/19 fixes to management of ED and schedule state.
* 2002/06/09 SA-1111 support (Christopher Hoover)
* 2002/06/01 remember frame when HC won't see EDs any more; use that info
* to fix urb unlink races caused by interrupt latency assumptions;
* minor ED field and function naming updates
* 2002/01/18 package as a patch for 2.5.3; this should match the
* 2.4.17 kernel modulo some bugs being fixed.
*
* 2001/10/18 merge pmac cleanup (Benjamin Herrenschmidt) and bugfixes
* from post-2.4.5 patches.
* 2001/09/20 URB_ZERO_PACKET support; hcca_dma portability, OPTi warning
* 2001/09/07 match PCI PM changes, errnos from Linus' tree
* 2001/05/05 fork 2.4.5 version into "hcd" framework, cleanup, simplify;
* pbook pci quirks gone (please fix pbook pci sw!) (db)
*
* 2001/04/08 Identify version on module load (gb)
* 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam);
pci_map_single (db)
* 2001/03/21 td and dev/ed allocation uses new pci_pool API (db)
* 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam)
*
* 2000/09/26 fixed races in removing the private portion of the urb
* 2000/09/07 disable bulk and control lists when unlinking the last
* endpoint descriptor in order to avoid unrecoverable errors on
* the Lucent chips. (rwc@sgi)
* 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some
* urb unlink probs, indentation fixes
* 2000/08/11 various oops fixes mostly affecting iso and cleanup from
* device unplugs.
* 2000/06/28 use PCI hotplug framework, for better power management
* and for Cardbus support (David Brownell)
* 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling
* when the controller loses power; handle UE; cleanup; ...
*
* v5.2 1999/12/07 URB 3rd preview,
* v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi)
* v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume
* i386: HUB, Keyboard, Mouse, Printer
*
* v4.3 1999/10/27 multiple HCs, bulk_request
* v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes
* v4.1 1999/08/27 Randy Dunlap's - ISO API first impl.
* v4.0 1999/08/18
* v3.0 1999/06/25
* v2.1 1999/05/09 code clean up
* v2.0 1999/05/04
* v1.0 1999/04/27 initial release
*
* This file is licenced under the GPL.
*/
#if 0
#include <linux/config.h>
#ifdef CONFIG_USB_DEBUG
# define DEBUG
#else
# undef DEBUG
#endif
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h> /* for in_interrupt () */
#include <linux/usb.h>
#include "../core/hcd.h"
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>
#else
#include "ohci_config.h"
#include "../usb_wrapper.h"
#include "../core/hcd.h"
int USB_init_ani=1;
//#define OHCI_VERBOSE_DEBUG
#endif
/*
* TO DO:
*
* - "disabled" and "sleeping" should be in hcd->state
* - lots more testing!!
*/
#define DRIVER_VERSION "2003 Feb 24"
#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
/*-------------------------------------------------------------------------*/
// #define OHCI_VERBOSE_DEBUG /* not always helpful */
/* For initializing controller (mask in an HCFS mode too) */
#define OHCI_CONTROL_INIT \
(OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
#define OHCI_UNLINK_TIMEOUT (HZ / 10)
/*-------------------------------------------------------------------------*/
static const char hcd_name [] = "ohci-hcd";
#include "ohci.h"
static inline void disable (struct ohci_hcd *ohci)
{
ohci->disabled = 1;
ohci->hcd.state = USB_STATE_HALT;
}
#include "ohci-hub.c"
#include "ohci-dbg.c"
#include "ohci-mem.c"
#include "ohci-q.c"
/*-------------------------------------------------------------------------*/
/*
* queue up an urb for anything except the root hub
*/
static int ohci_urb_enqueue (
struct usb_hcd *hcd,
struct urb *urb,
int mem_flags
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct ed *ed;
urb_priv_t *urb_priv;
unsigned int pipe = urb->pipe;
int i, size = 0;
unsigned long flags;
int retval = 0;
#ifdef OHCI_VERBOSE_DEBUG
urb_print (urb, "SUB", usb_pipein (pipe));
#endif
/* every endpoint has a ed, locate and maybe (re)initialize it */
if (! (ed = ed_get (ohci, urb->dev, pipe, urb->interval)))
return -ENOMEM;
/* for the private part of the URB we need the number of TDs (size) */
switch (ed->type) {
case PIPE_CONTROL:
/* td_submit_urb() doesn't yet handle these */
if (urb->transfer_buffer_length > 4096)
return -EMSGSIZE;
/* 1 TD for setup, 1 for ACK, plus ... */
size = 2;
/* FALLTHROUGH */
// case PIPE_INTERRUPT:
// case PIPE_BULK:
default:
/* one TD for every 4096 Bytes (can be upto 8K) */
size += urb->transfer_buffer_length / 4096;
/* ... and for any remaining bytes ... */
if ((urb->transfer_buffer_length % 4096) != 0)
size++;
/* ... and maybe a zero length packet to wrap it up */
if (size == 0)
size++;
else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0
&& (urb->transfer_buffer_length
% usb_maxpacket (urb->dev, pipe,
usb_pipeout (pipe))) == 0)
size++;
break;
case PIPE_ISOCHRONOUS: /* number of packets from URB */
size = urb->number_of_packets;
break;
}
/* allocate the private part of the URB */
urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (struct td *),
mem_flags);
if (!urb_priv)
return -ENOMEM;
memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *));
/* fill the private part of the URB */
urb_priv->length = size;
urb_priv->ed = ed;
/* allocate the TDs (deferring hash chain updates) */
for (i = 0; i < size; i++) {
urb_priv->td [i] = td_alloc (ohci, mem_flags);
if (!urb_priv->td [i]) {
urb_priv->length = i;
urb_free_priv (ohci, urb_priv);
return -ENOMEM;
}
}
spin_lock_irqsave (&ohci->lock, flags);
/* don't submit to a dead HC */
if (ohci->disabled || ohci->sleeping) {
retval = -ENODEV;
goto fail;
}
/* schedule the ed if needed */
if (ed->state == ED_IDLE) {
retval = ed_schedule (ohci, ed);
if (retval < 0)
goto fail;
if (ed->type == PIPE_ISOCHRONOUS) {
u16 frame = le16_to_cpu (ohci->hcca->frame_no);
/* delay a few frames before the first TD */
frame += max_t (u16, 8, ed->interval);
frame &= ~(ed->interval - 1);
frame |= ed->branch;
urb->start_frame = frame;
/* yes, only URB_ISO_ASAP is supported, and
* urb->start_frame is never used as input.
*/
}
} else if (ed->type == PIPE_ISOCHRONOUS)
urb->start_frame = ed->last_iso + ed->interval;
/* fill the TDs and link them to the ed; and
* enable that part of the schedule, if needed
* and update count of queued periodic urbs
*/
urb->hcpriv = urb_priv;
td_submit_urb (ohci, urb);
fail:
if (retval)
urb_free_priv (ohci, urb_priv);
spin_unlock_irqrestore (&ohci->lock, flags);
return retval;
}
/*
* decouple the URB from the HC queues (TDs, urb_priv); it's
* already marked using urb->status. reporting is always done
* asynchronously, and we might be dealing with an urb that's
* partially transferred, or an ED with other urbs being unlinked.
*/
static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
#ifdef OHCI_VERBOSE_DEBUG
urb_print (urb, "UNLINK", 1);
#endif
spin_lock_irqsave (&ohci->lock, flags);
if (!ohci->disabled) {
urb_priv_t *urb_priv;
/* Unless an IRQ completed the unlink while it was being
* handed to us, flag it for unlink and giveback, and force
* some upcoming INTR_SF to call finish_unlinks()
*/
urb_priv = urb->hcpriv;
if (urb_priv) {
urb_priv->state = URB_DEL;
if (urb_priv->ed->state == ED_OPER)
start_urb_unlink (ohci, urb_priv->ed);
}
} else {
/*
* with HC dead, we won't respect hc queue pointers
* any more ... just clean up every urb's memory.
*/
if (urb->hcpriv) {
spin_unlock (&ohci->lock);
finish_urb (ohci, urb, NULL);
spin_lock (&ohci->lock);
}
}
spin_unlock_irqrestore (&ohci->lock, flags);
return 0;
}
/*-------------------------------------------------------------------------*/
/* frees config/altsetting state for endpoints,
* including ED memory, dummy TD, and bulk/intr data toggle
*/
static void
ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int epnum = ep & USB_ENDPOINT_NUMBER_MASK;
unsigned long flags;
struct ed *ed;
/* ASSERT: any requests/urbs are being unlinked */
/* ASSERT: nobody can be submitting urbs for this any more */
epnum <<= 1;
if (epnum != 0 && !(ep & USB_DIR_IN))
epnum |= 1;
rescan:
spin_lock_irqsave (&ohci->lock, flags);
ed = dev->ep [epnum];
if (!ed)
goto done;
if (!HCD_IS_RUNNING (ohci->hcd.state) || ohci->disabled)
ed->state = ED_IDLE;
switch (ed->state) {
case ED_UNLINK: /* wait for hw to finish? */
spin_unlock_irqrestore (&ohci->lock, flags);
set_current_state (TASK_UNINTERRUPTIBLE);
schedule_timeout (1);
goto rescan;
case ED_IDLE: /* fully unlinked */
if (list_empty (&ed->td_list)) {
td_free (ohci, ed->dummy);
ed_free (ohci, ed);
break;
}
/* else FALL THROUGH */
default:
/* caller was supposed to have unlinked any requests;
* that's not our job. can't recover; must leak ed.
*/
ohci_err (ohci, "ed %p (#%d) state %d%s\n",
ed, epnum, ed->state,
list_empty (&ed->td_list) ? "" : "(has tds)");
td_free (ohci, ed->dummy);
break;
}
dev->ep [epnum] = 0;
done:
spin_unlock_irqrestore (&ohci->lock, flags);
return;
}
static int ohci_get_frame (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
return le16_to_cpu (ohci->hcca->frame_no);
}
/*-------------------------------------------------------------------------*
* HC functions
*-------------------------------------------------------------------------*/
/* reset the HC and BUS */
static int hc_reset (struct ohci_hcd *ohci)
{
u32 temp;
u32 ints;
u32 control;
/* Disable HC interrupts */
writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
// acknowledge all pending interrupts
ints = readl(&ohci->regs->intrstatus);
writel (ints, &ohci->regs->intrstatus);
if (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
// takeover without negotiation - there is noone to negotiate with
control = readl (&ohci->regs->control) & ~OHCI_CTRL_IR;
writel (control, &ohci->regs->control);
}
ohci_dbg (ohci, "USB HC reset_hc %s: ctrl = 0x%x ;\n",
hcd_to_bus (&ohci->hcd)->bus_name,
readl (&ohci->regs->control));
/* Reset USB (needed by some controllers); RemoteWakeupConnected
* saved if boot firmware (BIOS/SMM/...) told us it's connected
*/
ohci->hc_control = readl (&ohci->regs->control);
ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */
writel (ohci->hc_control, &ohci->regs->control);
// flush those pci writes
(void) readl (&ohci->regs->control);
wait_ms (50);
/* HC Reset requires max 10 us delay */
writel (OHCI_HCR, &ohci->regs->cmdstatus);
temp = 30; /* ... allow extra time */
while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
if (--temp == 0) {
ohci_err (ohci, "USB HC reset timed out!\n");
return -1;
}
udelay (1);
}
/* now we're in the SUSPEND state ... must go OPERATIONAL
* within 2msec else HC enters RESUME
*
* ... but some hardware won't init fmInterval "by the book"
* (SiS, OPTi ...), so reset again instead. SiS doesn't need
* this if we write fmInterval after we're OPERATIONAL.
*/
writel (ohci->hc_control, &ohci->regs->control);
// flush those pci writes
(void) readl (&ohci->regs->control);
return 0;
}
/*-------------------------------------------------------------------------*/
#define FI 0x2edf /* 12000 bits per frame (-1) */
#define LSTHRESH 0x628 /* lowspeed bit threshold */
/* Start an OHCI controller, set the BUS operational
* enable interrupts
* connect the virtual root hub
*/
static int hc_start (struct ohci_hcd *ohci)
{
u32 mask, tmp;
struct usb_device *udev;
struct usb_bus *bus;
spin_lock_init (&ohci->lock);
ohci->disabled = 1;
ohci->sleeping = 0;
/* Tell the controller where the control and bulk lists are
* The lists are empty now. */
writel (0, &ohci->regs->ed_controlhead);
writel (0, &ohci->regs->ed_bulkhead);
/* a reset clears this */
writel ((u32) ohci->hcca_dma, &ohci->regs->hcca);
// usbprintk("HCCA: %p \n",ohci->regs->hcca);
/* force default fmInterval (we won't adjust it); init thresholds
* for last FS and LS packets, reserve 90% for periodic.
*/
writel ((((6 * (FI - 210)) / 7) << 16) | FI, &ohci->regs->fminterval);
writel (((9 * FI) / 10) & 0x3fff, &ohci->regs->periodicstart);
writel (LSTHRESH, &ohci->regs->lsthresh);
/* some OHCI implementations are finicky about how they init.
* bogus values here mean not even enumeration could work.
*/
if ((readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
|| !readl (&ohci->regs->periodicstart)) {
ohci_err (ohci, "init err\n");
return -EOVERFLOW;
}
/* start controller operations */
ohci->hc_control &= OHCI_CTRL_RWC;
ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
ohci->disabled = 0;
writel (ohci->hc_control, &ohci->regs->control);
/* Choose the interrupts we care about now, others later on demand */
mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH;
writel (mask, &ohci->regs->intrstatus);
writel (mask, &ohci->regs->intrenable);
/* handle root hub init quirks ... */
tmp = roothub_a (ohci);
tmp &= ~(RH_A_PSM | RH_A_OCPM);
if (ohci->flags & OHCI_QUIRK_SUPERIO) {
/* NSC 87560 and maybe others */
tmp |= RH_A_NOCP;
tmp &= ~(RH_A_POTPGT | RH_A_NPS);
} else {
/* hub power always on; required for AMD-756 and some
* Mac platforms, use this mode everywhere by default
*/
tmp |= RH_A_NPS;
}
writel (tmp, &ohci->regs->roothub.a);
writel (RH_HS_LPSC, &ohci->regs->roothub.status);
writel (0, &ohci->regs->roothub.b);
// flush those pci writes
(void) readl (&ohci->regs->control);
// POTPGT delay is bits 24-31, in 2 ms units.
mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
/* connect the virtual root hub */
bus = hcd_to_bus (&ohci->hcd);
bus->root_hub = udev = usb_alloc_dev (NULL, bus);
ohci->hcd.state = USB_STATE_READY;
if (!udev) {
disable (ohci);
ohci->hc_control &= ~OHCI_CTRL_HCFS;
writel (ohci->hc_control, &ohci->regs->control);
ohci_err(ohci,"out of mem");
return -ENOMEM;
}
usb_connect (udev);
udev->speed = USB_SPEED_FULL;
if (hcd_register_root (&ohci->hcd) != 0) {
usb_put_dev (udev);
bus->root_hub = NULL;
disable (ohci);
ohci->hc_control &= ~OHCI_CTRL_HCFS;
writel (ohci->hc_control, &ohci->regs->control);
return -ENODEV;
}
create_debug_files (ohci);
return 0;
}
/*-------------------------------------------------------------------------*/
/* an interrupt happens */
static void ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct ohci_regs *regs = ohci->regs;
int ints;
/* we can eliminate a (slow) readl() if _only_ WDH caused this irq */
if ((ohci->hcca->done_head != 0)
&& ! (le32_to_cpup (&ohci->hcca->done_head) & 0x01)) {
ints = OHCI_INTR_WDH;
/* cardbus/... hardware gone before remove() */
} else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
disable (ohci);
ohci_dbg (ohci, "device removed!\n");
return;
/* interrupt for some other device? */
} else if ((ints &= readl (&regs->intrenable)) == 0) {
return;
}
if (ints & OHCI_INTR_UE) {
disable (ohci);
ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n");
// e.g. due to PCI Master/Target Abort
ohci_dump (ohci, 1);
hc_reset (ohci);
}
if (ints & OHCI_INTR_WDH) {
if (USB_init_ani) usbprintk("I");
writel (OHCI_INTR_WDH, &regs->intrdisable);
dl_done_list (ohci, dl_reverse_done_list (ohci), ptregs);
writel (OHCI_INTR_WDH, &regs->intrenable);
}
/* could track INTR_SO to reduce available PCI/... bandwidth */
/* handle any pending URB/ED unlinks, leaving INTR_SF enabled
* when there's still unlinking to be done (next frame).
*/
spin_lock (&ohci->lock);
if (ohci->ed_rm_list)
finish_unlinks (ohci, le16_to_cpu (ohci->hcca->frame_no),
ptregs);
if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list)
writel (OHCI_INTR_SF, &regs->intrdisable);
spin_unlock (&ohci->lock);
writel (ints, &regs->intrstatus);
writel (OHCI_INTR_MIE, &regs->intrenable);
// flush those pci writes
(void) readl (&ohci->regs->control);
}
/*-------------------------------------------------------------------------*/
static void ohci_stop (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
struct ohci_regs *regs = ohci->regs;
int ints;
ohci_dbg (ohci, "stop %s controller%s\n",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
ohci->disabled ? " (disabled)" : ""
);
ohci_dump (ohci, 1);
if (!ohci->disabled)
hc_reset (ohci);
// Disable all interrupts
writel (OHCI_INTR_MIE, &regs->intrdisable);
// acknowledge all pending interrupts
ints = readl(&regs->intrstatus);
writel (ints, &regs->intrstatus);
// flush register writes
(void) readl (&ohci->regs->control);
remove_debug_files (ohci);
ohci_mem_cleanup (ohci);
if (ohci->hcca) {
pci_free_consistent (ohci->hcd.pdev, sizeof *ohci->hcca,
ohci->hcca, ohci->hcca_dma);
ohci->hcca = NULL;
ohci->hcca_dma = 0;
}
}
/*-------------------------------------------------------------------------*/
// FIXME: this restart logic should be generic,
// and handle full hcd state cleanup
/* controller died; cleanup debris, then restart */
/* must not be called from interrupt context */
#ifdef CONFIG_PM
static int hc_restart (struct ohci_hcd *ohci)
{
int temp;
int i;
ohci->disabled = 1;
ohci->sleeping = 0;
if (hcd_to_bus (&ohci->hcd)->root_hub)
usb_disconnect (&hcd_to_bus (&ohci->hcd)->root_hub);
/* empty the interrupt branches */
for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0;
for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0;
/* no EDs to remove */
ohci->ed_rm_list = NULL;
/* empty control and bulk lists */
ohci->ed_controltail = NULL;
ohci->ed_bulktail = NULL;
if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
ohci_err (ohci, "can't restart, %d\n", temp);
return temp;
} else
ohci_dbg (ohci, "restart complete\n");
return 0;
}
#endif
/*-------------------------------------------------------------------------*/
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
MODULE_AUTHOR (DRIVER_AUTHOR);
MODULE_DESCRIPTION (DRIVER_INFO);
MODULE_LICENSE ("GPL");
#ifdef CONFIG_PCI
#include "ohci-pci.c"
#endif
#ifdef CONFIG_SA1111
#include "ohci-sa1111.c"
#endif
#if !(defined(CONFIG_PCI) || defined(CONFIG_SA1111))
#error "missing bus glue for ohci-hcd"
#endif

View file

@ -1,271 +0,0 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under GPL
*/
/*-------------------------------------------------------------------------*/
/*
* OHCI Root Hub ... the nonsharable stuff
*
* Registers don't need cpu_to_le32, that happens transparently
*/
/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
* The erratum (#4) description is incorrect. AMD's workaround waits
* till some bits (mostly reserved) are clear; ok for all revs.
*/
#define read_roothub(hc, register, mask) ({ \
u32 temp = readl (&hc->regs->roothub.register); \
if (temp == -1) \
disable (hc); \
else if (hc->flags & OHCI_QUIRK_AMD756) \
while (temp & mask) \
temp = readl (&hc->regs->roothub.register); \
temp; })
static u32 roothub_a (struct ohci_hcd *hc)
{ return read_roothub (hc, a, 0xfc0fe000); }
static inline u32 roothub_b (struct ohci_hcd *hc)
{ return readl (&hc->regs->roothub.b); }
static inline u32 roothub_status (struct ohci_hcd *hc)
{ return readl (&hc->regs->roothub.status); }
static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
/*-------------------------------------------------------------------------*/
#define dbg_port(hc,label,num,value) \
ohci_dbg (hc, \
"%s roothub.portstatus [%d] " \
"= 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s\n", \
label, num, temp, \
(temp & RH_PS_PRSC) ? " PRSC" : "", \
(temp & RH_PS_OCIC) ? " OCIC" : "", \
(temp & RH_PS_PSSC) ? " PSSC" : "", \
(temp & RH_PS_PESC) ? " PESC" : "", \
(temp & RH_PS_CSC) ? " CSC" : "", \
\
(temp & RH_PS_LSDA) ? " LSDA" : "", \
(temp & RH_PS_PPS) ? " PPS" : "", \
(temp & RH_PS_PRS) ? " PRS" : "", \
(temp & RH_PS_POCI) ? " POCI" : "", \
(temp & RH_PS_PSS) ? " PSS" : "", \
\
(temp & RH_PS_PES) ? " PES" : "", \
(temp & RH_PS_CCS) ? " CCS" : "" \
);
/*-------------------------------------------------------------------------*/
/* build "status change" packet (one or two bytes) from HC registers */
static int
ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports, i, changed = 0, length = 1;
ports = roothub_a (ohci) & RH_A_NDP;
if (ports > MAX_ROOT_PORTS) {
if (ohci->disabled)
return -ESHUTDOWN;
ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
ports, readl (&ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
return 0;
}
/* init status */
if (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC))
buf [0] = changed = 1;
else
buf [0] = 0;
if (ports > 7) {
buf [1] = 0;
length++;
}
/* look at each port */
for (i = 0; i < ports; i++) {
u32 status = roothub_portstatus (ohci, i);
status &= RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC
| RH_PS_OCIC | RH_PS_PRSC;
if (status) {
changed = 1;
if (i < 7)
buf [0] |= 1 << (i + 1);
else
buf [1] |= 1 << (i - 7);
}
}
return changed ? length : 0;
}
/*-------------------------------------------------------------------------*/
static void
ohci_hub_descriptor (
struct ohci_hcd *ohci,
struct usb_hub_descriptor *desc
) {
u32 rh = roothub_a (ohci);
int ports = rh & RH_A_NDP;
u16 temp;
desc->bDescriptorType = 0x29;
desc->bPwrOn2PwrGood = (rh & RH_A_POTPGT) >> 24;
desc->bHubContrCurrent = 0;
desc->bNbrPorts = ports;
temp = 1 + (ports / 8);
desc->bDescLength = 7 + 2 * temp;
temp = 0;
if (rh & RH_A_PSM) /* per-port power switching? */
temp |= 0x0001;
if (rh & RH_A_NOCP) /* no overcurrent reporting? */
temp |= 0x0010;
else if (rh & RH_A_OCPM) /* per-port overcurrent reporting? */
temp |= 0x0008;
desc->wHubCharacteristics = cpu_to_le16 (temp);
/* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
rh = roothub_b (ohci);
desc->bitmap [0] = rh & RH_B_DR;
if (ports > 7) {
desc->bitmap [1] = (rh & RH_B_DR) >> 8;
desc->bitmap [2] = desc->bitmap [3] = 0xff;
} else
desc->bitmap [1] = 0xff;
}
/*-------------------------------------------------------------------------*/
static int ohci_hub_control (
struct usb_hcd *hcd,
u16 typeReq,
u16 wValue,
u16 wIndex,
char *buf,
u16 wLength
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports = hcd_to_bus (hcd)->root_hub->maxchild;
u32 temp;
int retval = 0;
switch (typeReq) {
case ClearHubFeature:
switch (wValue) {
case C_HUB_OVER_CURRENT:
writel (RH_HS_OCIC, &ohci->regs->roothub.status);
case C_HUB_LOCAL_POWER:
break;
default:
goto error;
}
break;
case ClearPortFeature:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
temp = RH_PS_CCS;
break;
case USB_PORT_FEAT_C_ENABLE:
temp = RH_PS_PESC;
break;
case USB_PORT_FEAT_SUSPEND:
temp = RH_PS_POCI;
break;
case USB_PORT_FEAT_C_SUSPEND:
temp = RH_PS_PSSC;
break;
case USB_PORT_FEAT_POWER:
temp = RH_PS_LSDA;
break;
case USB_PORT_FEAT_C_CONNECTION:
temp = RH_PS_CSC;
break;
case USB_PORT_FEAT_C_OVER_CURRENT:
temp = RH_PS_OCIC;
break;
case USB_PORT_FEAT_C_RESET:
temp = RH_PS_PRSC;
break;
default:
goto error;
}
writel (temp, &ohci->regs->roothub.portstatus [wIndex]);
// readl (&ohci->regs->roothub.portstatus [wIndex]);
break;
case GetHubDescriptor:
ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
break;
case GetHubStatus:
temp = roothub_status (ohci) & ~(RH_HS_CRWE | RH_HS_DRWE);
*(u32 *) buf = cpu_to_le32 (temp);
break;
case GetPortStatus:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
temp = roothub_portstatus (ohci, wIndex);
*(u32 *) buf = cpu_to_le32 (temp);
#ifndef OHCI_VERBOSE_DEBUG
if (*(u16*)(buf+2)) /* only if wPortChange is interesting */
#endif
dbg_port (ohci, "GetStatus", wIndex + 1, temp);
break;
case SetHubFeature:
switch (wValue) {
case C_HUB_OVER_CURRENT:
// FIXME: this can be cleared, yes?
case C_HUB_LOCAL_POWER:
break;
default:
goto error;
}
break;
case SetPortFeature:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
writel (RH_PS_PSS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_POWER:
writel (RH_PS_PPS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_RESET:
temp = readl (&ohci->regs->roothub.portstatus [wIndex]);
if (temp & RH_PS_CCS)
writel (RH_PS_PRS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
default:
goto error;
}
break;
default:
error:
/* "protocol stall" on error */
retval = -EPIPE;
}
return retval;
}

View file

@ -1,146 +0,0 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
*/
/*-------------------------------------------------------------------------*/
/*
* There's basically three types of memory:
* - data used only by the HCD ... kmalloc is fine
* - async and periodic schedules, shared by HC and HCD ... these
* need to use pci_pool or pci_alloc_consistent
* - driver buffers, read/written by HC ... the hcd glue or the
* device driver provides us with dma addresses
*
* There's also PCI "register" data, which is memory mapped.
* No memory seen by this driver is pagable.
*/
/*-------------------------------------------------------------------------*/
static struct usb_hcd *ohci_hcd_alloc (void)
{
struct ohci_hcd *ohci;
ohci = (struct ohci_hcd *) kmalloc (sizeof *ohci, GFP_KERNEL);
if (ohci != 0) {
memset (ohci, 0, sizeof (struct ohci_hcd));
return &ohci->hcd;
}
return 0;
}
static void ohci_hcd_free (struct usb_hcd *hcd)
{
kfree (hcd_to_ohci (hcd));
}
/*-------------------------------------------------------------------------*/
static int ohci_mem_init (struct ohci_hcd *ohci)
{
ohci->td_cache = pci_pool_create ("ohci_td", ohci->hcd.pdev,
sizeof (struct td),
32 /* byte alignment */,
0 /* no page-crossing issues */);
if (!ohci->td_cache)
return -ENOMEM;
ohci->ed_cache = pci_pool_create ("ohci_ed", ohci->hcd.pdev,
sizeof (struct ed),
16 /* byte alignment */,
0 /* no page-crossing issues */);
if (!ohci->ed_cache) {
pci_pool_destroy (ohci->td_cache);
return -ENOMEM;
}
return 0;
}
static void ohci_mem_cleanup (struct ohci_hcd *ohci)
{
if (ohci->td_cache) {
pci_pool_destroy (ohci->td_cache);
ohci->td_cache = 0;
}
if (ohci->ed_cache) {
pci_pool_destroy (ohci->ed_cache);
ohci->ed_cache = 0;
}
}
/*-------------------------------------------------------------------------*/
/* ohci "done list" processing needs this mapping */
static inline struct td *
dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma)
{
struct td *td;
td_dma &= TD_MASK;
td = hc->td_hash [TD_HASH_FUNC(td_dma)];
while (td && td->td_dma != td_dma)
td = td->td_hash;
return td;
}
/* TDs ... */
static struct td *
td_alloc (struct ohci_hcd *hc, int mem_flags)
{
dma_addr_t dma;
struct td *td;
td = pci_pool_alloc (hc->td_cache, mem_flags, &dma);
if (td) {
/* in case hc fetches it, make it look dead */
memset (td, 0, sizeof *td);
td->hwNextTD = cpu_to_le32 (dma);
td->td_dma = dma;
/* hashed in td_fill */
}
return td;
}
static void
td_free (struct ohci_hcd *hc, struct td *td)
{
struct td **prev = &hc->td_hash [TD_HASH_FUNC (td->td_dma)];
while (*prev && *prev != td)
prev = &(*prev)->td_hash;
if (*prev)
*prev = td->td_hash;
else if ((td->hwINFO & TD_DONE) != 0)
ohci_dbg (hc, "no hash for td %p\n", td);
pci_pool_free (hc->td_cache, td, td->td_dma);
}
/*-------------------------------------------------------------------------*/
/* EDs ... */
static struct ed *
ed_alloc (struct ohci_hcd *hc, int mem_flags)
{
dma_addr_t dma;
struct ed *ed;
ed = pci_pool_alloc (hc->ed_cache, mem_flags, &dma);
if (ed) {
memset (ed, 0, sizeof (*ed));
INIT_LIST_HEAD (&ed->td_list);
ed->dma = dma;
}
return ed;
}
static void
ed_free (struct ohci_hcd *hc, struct ed *ed)
{
pci_pool_free (hc->ed_cache, ed, ed->dma);
}

View file

@ -1,403 +0,0 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* [ Initialisation is based on Linus' ]
* [ uhci code and gregs ohci fragments ]
* [ (C) Copyright 1999 Linus Torvalds ]
* [ (C) Copyright 1999 Gregory P. Smith]
*
* PCI Bus Glue
*
* This file is licenced under the GPL.
*/
#ifdef CONFIG_PMAC_PBOOK
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/pci-bridge.h>
#include <asm/prom.h>
#ifndef CONFIG_PM
# define CONFIG_PM
#endif
#endif
#ifndef CONFIG_PCI
#error "This file is PCI bus glue. CONFIG_PCI must be defined."
#endif
/*-------------------------------------------------------------------------*/
static int __devinit
ohci_pci_start (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ret;
if (hcd->pdev) {
ohci->hcca = pci_alloc_consistent (hcd->pdev,
sizeof *ohci->hcca, &ohci->hcca_dma);
if (!ohci->hcca)
return -ENOMEM;
/* AMD 756, for most chips (early revs), corrupts register
* values on read ... so enable the vendor workaround.
*/
if (hcd->pdev->vendor == PCI_VENDOR_ID_AMD
&& hcd->pdev->device == 0x740c) {
ohci->flags = OHCI_QUIRK_AMD756;
ohci_info (ohci, "AMD756 erratum 4 workaround\n");
}
/* FIXME for some of the early AMD 760 southbridges, OHCI
* won't work at all. blacklist them.
*/
/* Apple's OHCI driver has a lot of bizarre workarounds
* for this chip. Evidently control and bulk lists
* can get confused. (B&W G3 models, and ...)
*/
else if (hcd->pdev->vendor == PCI_VENDOR_ID_OPTI
&& hcd->pdev->device == 0xc861) {
ohci_info (ohci,
"WARNING: OPTi workarounds unavailable\n");
}
/* Check for NSC87560. We have to look at the bridge (fn1) to
* identify the USB (fn2). This quirk might apply to more or
* even all NSC stuff.
*/
else if (hcd->pdev->vendor == PCI_VENDOR_ID_NS) {
struct pci_dev *b, *hc;
hc = hcd->pdev;
b = pci_find_slot (hc->bus->number,
PCI_DEVFN (PCI_SLOT (hc->devfn), 1));
if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
&& b->vendor == PCI_VENDOR_ID_NS) {
ohci->flags |= OHCI_QUIRK_SUPERIO;
ohci_info (ohci, "Using NSC SuperIO setup\n");
}
}
}
memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
if ((ret = ohci_mem_init (ohci)) < 0) {
ohci_stop (hcd);
return ret;
}
ohci->regs = hcd->regs;
if (hc_reset (ohci) < 0) {
ohci_stop (hcd);
return -ENODEV;
}
if (hc_start (ohci) < 0) {
ohci_err (ohci, "can't start\n");
ohci_stop (hcd);
return -EBUSY;
}
#ifdef DEBUG
ohci_dump (ohci, 1);
#endif
return 0;
}
#ifdef CONFIG_PM
static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
u16 cmd;
if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
ohci_dbg (ohci, "can't suspend (state is %s)\n",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
return -EIO;
}
/* act as if usb suspend can always be used */
ohci_dbg (ohci, "suspend to %d\n", state);
ohci->sleeping = 1;
/* First stop processing */
spin_lock_irqsave (&ohci->lock, flags);
ohci->hc_control &=
~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
writel (ohci->hc_control, &ohci->regs->control);
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
(void) readl (&ohci->regs->intrstatus);
spin_unlock_irqrestore (&ohci->lock, flags);
/* Wait a frame or two */
mdelay (1);
if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
mdelay (1);
#ifdef CONFIG_PMAC_PBOOK
if (_machine == _MACH_Pmac)
disable_irq (hcd->pdev->irq);
/* else, 2.4 assumes shared irqs -- don't disable */
#endif
/* Enable remote wakeup */
writel (readl (&ohci->regs->intrenable) | OHCI_INTR_RD,
&ohci->regs->intrenable);
/* Suspend chip and let things settle down a bit */
ohci->hc_control = OHCI_USB_SUSPEND;
writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (500); /* No schedule here ! */
switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
case OHCI_USB_RESET:
ohci_dbg (ohci, "suspend->reset ?\n");
break;
case OHCI_USB_RESUME:
ohci_dbg (ohci, "suspend->resume ?\n");
break;
case OHCI_USB_OPER:
ohci_dbg (ohci, "suspend->operational ?\n");
break;
case OHCI_USB_SUSPEND:
ohci_dbg (ohci, "suspended\n");
break;
}
/* In some rare situations, Apple's OHCI have happily trashed
* memory during sleep. We disable its bus master bit during
* suspend
*/
pci_read_config_word (hcd->pdev, PCI_COMMAND, &cmd);
cmd &= ~PCI_COMMAND_MASTER;
pci_write_config_word (hcd->pdev, PCI_COMMAND, cmd);
#ifdef CONFIG_PMAC_PBOOK
{
struct device_node *of_node;
/* Disable USB PAD & cell clock */
of_node = pci_device_to_OF_node (hcd->pdev);
if (of_node)
pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
}
#endif
return 0;
}
static int ohci_pci_resume (struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int temp;
int retval = 0;
unsigned long flags;
#ifdef CONFIG_PMAC_PBOOK
{
struct device_node *of_node;
/* Re-enable USB PAD & cell clock */
of_node = pci_device_to_OF_node (hcd->pdev);
if (of_node)
pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1);
}
#endif
/* did we suspend, or were we powered off? */
ohci->hc_control = readl (&ohci->regs->control);
temp = ohci->hc_control & OHCI_CTRL_HCFS;
#ifdef DEBUG
/* the registers may look crazy here */
ohci_dump_status (ohci, 0, 0);
#endif
/* Re-enable bus mastering */
pci_set_master (ohci->hcd.pdev);
switch (temp) {
case OHCI_USB_RESET: // lost power
ohci_info (ohci, "USB restart\n");
retval = hc_restart (ohci);
break;
case OHCI_USB_SUSPEND: // host wakeup
case OHCI_USB_RESUME: // remote wakeup
ohci_info (ohci, "USB continue from %s wakeup\n",
(temp == OHCI_USB_SUSPEND)
? "host" : "remote");
ohci->hc_control = OHCI_USB_RESUME;
writel (ohci->hc_control, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (20); /* no schedule here ! */
/* Some controllers (lucent) need a longer delay here */
mdelay (15);
temp = readl (&ohci->regs->control);
temp = ohci->hc_control & OHCI_CTRL_HCFS;
if (temp != OHCI_USB_RESUME) {
ohci_err (ohci, "controller won't resume\n");
ohci->disabled = 1;
retval = -EIO;
break;
}
/* Some chips likes being resumed first */
writel (OHCI_USB_OPER, &ohci->regs->control);
(void) readl (&ohci->regs->control);
mdelay (3);
/* Then re-enable operations */
spin_lock_irqsave (&ohci->lock, flags);
ohci->disabled = 0;
ohci->sleeping = 0;
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
if (!ohci->ed_rm_list) {
if (ohci->ed_controltail)
ohci->hc_control |= OHCI_CTRL_CLE;
if (ohci->ed_bulktail)
ohci->hc_control |= OHCI_CTRL_BLE;
}
hcd->state = USB_STATE_READY;
writel (ohci->hc_control, &ohci->regs->control);
/* trigger a start-frame interrupt (why?) */
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
/* Check for a pending done list */
writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
(void) readl (&ohci->regs->intrdisable);
spin_unlock_irqrestore (&ohci->lock, flags);
#ifdef CONFIG_PMAC_PBOOK
if (_machine == _MACH_Pmac)
enable_irq (hcd->pdev->irq);
#endif
if (ohci->hcca->done_head)
dl_done_list (ohci, dl_reverse_done_list (ohci), NULL);
writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
/* assume there are TDs on the bulk and control lists */
writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus);
// ohci_dump_status (ohci);
ohci_dbg (ohci, "sleeping = %d, disabled = %d\n",
ohci->sleeping, ohci->disabled);
break;
default:
ohci_warn (ohci, "odd PCI resume\n");
}
return retval;
}
#endif /* CONFIG_PM */
/*-------------------------------------------------------------------------*/
static const struct hc_driver ohci_pci_hc_driver = {
.description = hcd_name,
/*
* generic hardware linkage
*/
.irq = ohci_irq,
.flags = HCD_MEMORY | HCD_USB11,
/*
* basic lifecycle operations
*/
.start = ohci_pci_start,
#ifdef CONFIG_PM
.suspend = ohci_pci_suspend,
.resume = ohci_pci_resume,
#endif
.stop = ohci_stop,
/*
* memory lifecycle (except per-request)
*/
.hcd_alloc = ohci_hcd_alloc,
.hcd_free = ohci_hcd_free,
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = ohci_urb_enqueue,
.urb_dequeue = ohci_urb_dequeue,
.endpoint_disable = ohci_endpoint_disable,
/*
* scheduling support
*/
.get_frame_number = ohci_get_frame,
/*
* root hub support
*/
.hub_status_data = ohci_hub_status_data,
.hub_control = ohci_hub_control,
};
/*-------------------------------------------------------------------------*/
static const struct pci_device_id __devinitdata pci_ids [] = { {
/* handle any USB OHCI controller */
.class = (PCI_CLASS_SERIAL_USB << 8) | 0x10,
.class_mask = ~0,
.driver_data = (unsigned long) &ohci_pci_hc_driver,
/* no matter who makes it */
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
}, { /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE (pci, pci_ids);
/* pci driver glue; this is a "new style" PCI driver module */
static struct pci_driver ohci_pci_driver = {
.name = (char *) hcd_name,
.id_table = pci_ids,
.probe = usb_hcd_pci_probe,
.remove = usb_hcd_pci_remove,
#ifdef CONFIG_PM
.suspend = usb_hcd_pci_suspend,
.resume = usb_hcd_pci_resume,
#endif
};
static int __init ohci_hcd_pci_init (void)
{
printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name);
if (usb_disabled())
return -ENODEV;
printk (KERN_DEBUG "%s: block sizes: ed %Zd td %Zd\n", hcd_name,
sizeof (struct ed), sizeof (struct td));
return pci_module_init (&ohci_pci_driver);
}
module_init (ohci_hcd_pci_init);
/*-------------------------------------------------------------------------*/
static void __exit ohci_hcd_pci_cleanup (void)
{
pci_unregister_driver (&ohci_pci_driver);
}
module_exit (ohci_hcd_pci_cleanup);

File diff suppressed because it is too large Load diff

View file

@ -1,406 +0,0 @@
/*
* OHCI HCD (Host Controller Driver) for USB.
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
*
* This file is licenced under the GPL.
*/
/*
* OHCI Endpoint Descriptor (ED) ... holds TD queue
* See OHCI spec, section 4.2
*
* This is a "Queue Head" for those transfers, which is why
* both EHCI and UHCI call similar structures a "QH".
*/
struct ed {
/* first fields are hardware-specified, le32 */
__u32 hwINFO; /* endpoint config bitmap */
/* info bits defined by hcd */
#define ED_DEQUEUE __constant_cpu_to_le32(1 << 27)
/* info bits defined by the hardware */
#define ED_ISO __constant_cpu_to_le32(1 << 15)
#define ED_SKIP __constant_cpu_to_le32(1 << 14)
#define ED_LOWSPEED __constant_cpu_to_le32(1 << 13)
#define ED_OUT __constant_cpu_to_le32(0x01 << 11)
#define ED_IN __constant_cpu_to_le32(0x02 << 11)
__u32 hwTailP; /* tail of TD list */
__u32 hwHeadP; /* head of TD list (hc r/w) */
#define ED_C __constant_cpu_to_le32(0x02) /* toggle carry */
#define ED_H __constant_cpu_to_le32(0x01) /* halted */
__u32 hwNextED; /* next ED in list */
/* rest are purely for the driver's use */
dma_addr_t dma; /* addr of ED */
struct td *dummy; /* next TD to activate */
/* host's view of schedule */
struct ed *ed_next; /* on schedule or rm_list */
struct ed *ed_prev; /* for non-interrupt EDs */
struct list_head td_list; /* "shadow list" of our TDs */
/* create --> IDLE --> OPER --> ... --> IDLE --> destroy
* usually: OPER --> UNLINK --> (IDLE | OPER) --> ...
* some special cases : OPER --> IDLE ...
*/
u8 state; /* ED_{IDLE,UNLINK,OPER} */
#define ED_IDLE 0x00 /* NOT linked to HC */
#define ED_UNLINK 0x01 /* being unlinked from hc */
#define ED_OPER 0x02 /* IS linked to hc */
u8 type; /* PIPE_{BULK,...} */
/* periodic scheduling params (for intr and iso) */
u8 branch;
u16 interval;
u16 load;
u16 last_iso; /* iso only */
/* HC may see EDs on rm_list until next frame (frame_no == tick) */
u16 tick;
} __attribute__ ((aligned(16)));
#define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */
/*
* OHCI Transfer Descriptor (TD) ... one per transfer segment
* See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt)
* and 4.3.2 (iso)
*/
struct td {
/* first fields are hardware-specified, le32 */
__u32 hwINFO; /* transfer info bitmask */
/* hwINFO bits for both general and iso tds: */
#define TD_CC 0xf0000000 /* condition code */
#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f)
//#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28)
#define TD_DI 0x00E00000 /* frames before interrupt */
#define TD_DI_SET(X) (((X) & 0x07)<< 21)
/* these two bits are available for definition/use by HCDs in both
* general and iso tds ... others are available for only one type
*/
#define TD_DONE 0x00020000 /* retired to donelist */
#define TD_ISO 0x00010000 /* copy of ED_ISO */
/* hwINFO bits for general tds: */
#define TD_EC 0x0C000000 /* error count */
#define TD_T 0x03000000 /* data toggle state */
#define TD_T_DATA0 0x02000000 /* DATA0 */
#define TD_T_DATA1 0x03000000 /* DATA1 */
#define TD_T_TOGGLE 0x00000000 /* uses ED_C */
#define TD_DP 0x00180000 /* direction/pid */
#define TD_DP_SETUP 0x00000000 /* SETUP pid */
#define TD_DP_IN 0x00100000 /* IN pid */
#define TD_DP_OUT 0x00080000 /* OUT pid */
/* 0x00180000 rsvd */
#define TD_R 0x00040000 /* round: short packets OK? */
/* (no hwINFO #defines yet for iso tds) */
__u32 hwCBP; /* Current Buffer Pointer (or 0) */
__u32 hwNextTD; /* Next TD Pointer */
__u32 hwBE; /* Memory Buffer End Pointer */
/* PSW is only for ISO */
#define MAXPSW 1 /* hardware allows 8 */
__u16 hwPSW [MAXPSW];
/* rest are purely for the driver's use */
__u8 index;
struct ed *ed;
struct td *td_hash; /* dma-->td hashtable */
struct td *next_dl_td;
struct urb *urb;
dma_addr_t td_dma; /* addr of this TD */
dma_addr_t data_dma; /* addr of data it points to */
struct list_head td_list; /* "shadow list", TDs on same ED */
} __attribute__ ((aligned(32))); /* c/b/i need 16; only iso needs 32 */
#define TD_MASK ((u32)~0x1f) /* strip hw status in low addr bits */
/*
* Hardware transfer status codes -- CC from td->hwINFO or td->hwPSW
*/
#define TD_CC_NOERROR 0x00
#define TD_CC_CRC 0x01
#define TD_CC_BITSTUFFING 0x02
#define TD_CC_DATATOGGLEM 0x03
#define TD_CC_STALL 0x04
#define TD_DEVNOTRESP 0x05
#define TD_PIDCHECKFAIL 0x06
#define TD_UNEXPECTEDPID 0x07
#define TD_DATAOVERRUN 0x08
#define TD_DATAUNDERRUN 0x09
/* 0x0A, 0x0B reserved for hardware */
#define TD_BUFFEROVERRUN 0x0C
#define TD_BUFFERUNDERRUN 0x0D
/* 0x0E, 0x0F reserved for HCD */
#define TD_NOTACCESSED 0x0F
/* map OHCI TD status codes (CC) to errno values */
static const int cc_to_error [16] = {
/* No Error */ 0,
/* CRC Error */ -EILSEQ,
/* Bit Stuff */ -EPROTO,
/* Data Togg */ -EILSEQ,
/* Stall */ -EPIPE,
/* DevNotResp */ -ETIMEDOUT,
/* PIDCheck */ -EPROTO,
/* UnExpPID */ -EPROTO,
/* DataOver */ -EOVERFLOW,
/* DataUnder */ -EREMOTEIO,
/* (for hw) */ -EIO,
/* (for hw) */ -EIO,
/* BufferOver */ -ECOMM,
/* BuffUnder */ -ENOSR,
/* (for HCD) */ -EALREADY,
/* (for HCD) */ -EALREADY
};
/*
* The HCCA (Host Controller Communications Area) is a 256 byte
* structure defined section 4.4.1 of the OHCI spec. The HC is
* told the base address of it. It must be 256-byte aligned.
*/
struct ohci_hcca {
#define NUM_INTS 32
__u32 int_table [NUM_INTS]; /* periodic schedule */
__u16 frame_no; /* current frame number */
__u16 pad1; /* set to 0 on each frame_no change */
__u32 done_head; /* info returned for an interrupt */
u8 reserved_for_hc [116];
u8 what [4]; /* spec only identifies 252 bytes :) */
} __attribute__ ((aligned(256)));
/*
* This is the structure of the OHCI controller's memory mapped I/O region.
* You must use readl() and writel() (in <asm/io.h>) to access these fields!!
* Layout is in section 7 (and appendix B) of the spec.
*/
struct ohci_regs {
/* control and status registers (section 7.1) */
__u32 revision;
__u32 control;
__u32 cmdstatus;
__u32 intrstatus;
__u32 intrenable;
__u32 intrdisable;
/* memory pointers (section 7.2) */
__u32 hcca;
__u32 ed_periodcurrent;
__u32 ed_controlhead;
__u32 ed_controlcurrent;
__u32 ed_bulkhead;
__u32 ed_bulkcurrent;
__u32 donehead;
/* frame counters (section 7.3) */
__u32 fminterval;
__u32 fmremaining;
__u32 fmnumber;
__u32 periodicstart;
__u32 lsthresh;
/* Root hub ports (section 7.4) */
struct ohci_roothub_regs {
__u32 a;
__u32 b;
__u32 status;
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports (RH_A_NDP) */
__u32 portstatus [MAX_ROOT_PORTS];
} roothub;
/* and optional "legacy support" registers (appendix B) at 0x0100 */
} __attribute__ ((aligned(32)));
/* OHCI CONTROL AND STATUS REGISTER MASKS */
/*
* HcControl (control) register masks
*/
#define OHCI_CTRL_CBSR (3 << 0) /* control/bulk service ratio */
#define OHCI_CTRL_PLE (1 << 2) /* periodic list enable */
#define OHCI_CTRL_IE (1 << 3) /* isochronous enable */
#define OHCI_CTRL_CLE (1 << 4) /* control list enable */
#define OHCI_CTRL_BLE (1 << 5) /* bulk list enable */
#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */
/* pre-shifted values for HCFS */
# define OHCI_USB_RESET (0 << 6)
# define OHCI_USB_RESUME (1 << 6)
# define OHCI_USB_OPER (2 << 6)
# define OHCI_USB_SUSPEND (3 << 6)
/*
* HcCommandStatus (cmdstatus) register masks
*/
#define OHCI_HCR (1 << 0) /* host controller reset */
#define OHCI_CLF (1 << 1) /* control list filled */
#define OHCI_BLF (1 << 2) /* bulk list filled */
#define OHCI_OCR (1 << 3) /* ownership change request */
#define OHCI_SOC (3 << 16) /* scheduling overrun count */
/*
* masks used with interrupt registers:
* HcInterruptStatus (intrstatus)
* HcInterruptEnable (intrenable)
* HcInterruptDisable (intrdisable)
*/
#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */
#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */
#define OHCI_INTR_SF (1 << 2) /* start frame */
#define OHCI_INTR_RD (1 << 3) /* resume detect */
#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */
#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */
#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */
#define OHCI_INTR_OC (1 << 30) /* ownership change */
#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */
/* OHCI ROOT HUB REGISTER MASKS */
/* roothub.portstatus [i] bits */
#define RH_PS_CCS 0x00000001 /* current connect status */
#define RH_PS_PES 0x00000002 /* port enable status*/
#define RH_PS_PSS 0x00000004 /* port suspend status */
#define RH_PS_POCI 0x00000008 /* port over current indicator */
#define RH_PS_PRS 0x00000010 /* port reset status */
#define RH_PS_PPS 0x00000100 /* port power status */
#define RH_PS_LSDA 0x00000200 /* low speed device attached */
#define RH_PS_CSC 0x00010000 /* connect status change */
#define RH_PS_PESC 0x00020000 /* port enable status change */
#define RH_PS_PSSC 0x00040000 /* port suspend status change */
#define RH_PS_OCIC 0x00080000 /* over current indicator change */
#define RH_PS_PRSC 0x00100000 /* port reset status change */
/* roothub.status bits */
#define RH_HS_LPS 0x00000001 /* local power status */
#define RH_HS_OCI 0x00000002 /* over current indicator */
#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */
#define RH_HS_LPSC 0x00010000 /* local power status change */
#define RH_HS_OCIC 0x00020000 /* over current indicator change */
#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */
/* roothub.b masks */
#define RH_B_DR 0x0000ffff /* device removable flags */
#define RH_B_PPCM 0xffff0000 /* port power control mask */
/* roothub.a masks */
#define RH_A_NDP (0xff << 0) /* number of downstream ports */
#define RH_A_PSM (1 << 8) /* power switching mode */
#define RH_A_NPS (1 << 9) /* no power switching */
#define RH_A_DT (1 << 10) /* device type (mbz) */
#define RH_A_OCPM (1 << 11) /* over current protection mode */
#define RH_A_NOCP (1 << 12) /* no over current protection */
#define RH_A_POTPGT (0xff << 24) /* power on to power good time */
/* hcd-private per-urb state */
typedef struct urb_priv {
struct ed *ed;
__u16 length; // # tds in this request
__u16 td_cnt; // tds already serviced
int state;
struct td *td [0]; // all TDs in this request
} urb_priv_t;
#define URB_DEL 1
#define TD_HASH_SIZE 64 /* power'o'two */
// sizeof (struct td) ~= 64 == 2^6 ...
#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE)
/*
* This is the full ohci controller description
*
* Note how the "proper" USB information is just
* a subset of what the full implementation needs. (Linus)
*/
struct ohci_hcd {
spinlock_t lock;
/*
* I/O memory used to communicate with the HC (dma-consistent)
*/
struct ohci_regs *regs;
/*
* main memory used to communicate with the HC (dma-consistent).
* hcd adds to schedule for a live hc any time, but removals finish
* only at the start of the next frame.
*/
struct ohci_hcca *hcca;
dma_addr_t hcca_dma;
struct ed *ed_rm_list; /* to be removed */
struct ed *ed_bulktail; /* last in bulk list */
struct ed *ed_controltail; /* last in ctrl list */
struct ed *periodic [NUM_INTS]; /* shadow int_table */
/*
* memory management for queue data structures
*/
struct pci_pool *td_cache;
struct pci_pool *ed_cache;
struct td *td_hash [TD_HASH_SIZE];
/*
* driver state
*/
int disabled; /* e.g. got a UE, we're hung */
int sleeping;
int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */
unsigned long flags; /* for HC bugs */
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
#define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */
// there are also chip quirks/bugs in init logic
/*
* framework state
*/
struct usb_hcd hcd;
};
#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd)
/*-------------------------------------------------------------------------*/
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
#define ohci_dbg(ohci, fmt, args...) \
dev_dbg ((ohci)->hcd.controller , fmt , ## args )
#define ohci_err(ohci, fmt, args...) \
dev_err ((ohci)->hcd.controller , fmt , ## args )
#define ohci_info(ohci, fmt, args...) \
dev_info ((ohci)->hcd.controller , fmt , ## args )
#define ohci_warn(ohci, fmt, args...) \
dev_warn ((ohci)->hcd.controller , fmt , ## args )
#ifdef OHCI_VERBOSE_DEBUG
# define ohci_vdbg ohci_dbg
#else
# define ohci_vdbg(ohci, fmt, args...) do { } while (0)
#endif

View file

@ -1,5 +0,0 @@
/*
* Configs for OHCI
*/
#define CONFIG_PCI

View file

@ -1,99 +0,0 @@
/*
* USB support for XBOX, based on Linux kernel source
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
*/
#include "../usb_wrapper.h"
void subsys_usb_init(void);
void module_exit_usb_exit(void);
extern struct pci_device_id *module_table_pci_ids;
// straigth call...
int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id);
void usb_hcd_pci_remove (struct pci_dev *dev);
void XPADInit(void);
void XPADRemove(void);
void XRemoteInit(void);
void XRemoteRemove(void);
extern int (*thread_handler)(void*);
int (*hub_thread_handler)(void*);
extern int nousb;
extern int USB_init_ani;
extern int xpad_num;
struct pci_dev xx_ohci_dev={
.vendor = 0,
.device = 0,
.bus = NULL,
.irq = 1, // currently not used...
.slot_name = "OHCI",
.dev = {.name = "PCI",.dma_mask=1},
.base = {0xfed00000},
.flags = {}
};
/*------------------------------------------------------------------------*/
void BootStartUSB(void)
{
int n;
nousb=0;
init_wrapper();
subsys_usb_init();
hub_thread_handler=thread_handler;
usb_hcd_pci_probe(&xx_ohci_dev,
module_table_pci_ids);
XPADInit();
XRemoteInit();
UsbKeyBoardInit();
// Find a few connected devices first...
for(n=0;n<3000;n++)
{
USBGetEvents();
wait_ms(1);
if (xpad_num!=0) { // Houston, we have a XPAD!
if (n>200) break;
}
}
USB_init_ani=0; // No more animation
}
/*------------------------------------------------------------------------*/
void USBGetEvents(void)
{
inc_jiffies(1);
do_all_timers();
hub_thread_handler(NULL);
handle_irqs(-1);
}
/*------------------------------------------------------------------------*/
void BootStopUSB(void)
{
int n;
XPADRemove();
XRemoteRemove();
UsbKeyBoardRemove();
for(n=0;n<100;n++)
{
USBGetEvents();
wait_ms(1);
}
module_exit_usb_exit();
usb_hcd_pci_remove(&xx_ohci_dev);
}
/*------------------------------------------------------------------------*/

View file

@ -1,4 +0,0 @@
O_TARGET := usbwrapper.o BootUSB.o linuxwrapper.o xpad.o xremote.o usbkey.o risefall.o
include $(TOPDIR)/Rules.make

View file

@ -1,271 +0,0 @@
/*
* USB support based on Linux kernel source
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
* Concept:
*
* 1) Forget all device interrupts, scheduling, semaphores, threads etc.
* 1a) Forget all DMA and PCI helper functions
* 2) Forget usbdevfs, procfs and ioctls
* 3) Emulate OHCI interrupts and root hub timer by polling
* 4) Emulate hub kernel thread by polling
* 5) Emulate synchronous USB-messages (usb_*_msg) with busy waiting
*
* To be done:
* 6) Remove code bloat
*
*/
#include "../usb_wrapper.h"
/* internal state */
static struct pci_dev *pci_probe_dev;
extern int (*thread_handler)(void*);
extern void* thread_parm;
struct my_irqs reg_irqs[MAX_IRQS];
int num_irqs;
int need_wakeup;
int my_jiffies;
struct timer_list *main_timer_list[MAX_TIMERS];
struct dummy_process act_cur={0};
struct dummy_process *my_current;
int (*thread_handler)(void*);
void* thread_parm;
#define MAX_DRVS 8
static struct device_driver *m_drivers[MAX_DRVS];
static int drvs_num;
/*------------------------------------------------------------------------*/
/*
* Helper functions for top-level system
*/
/*------------------------------------------------------------------------*/
void init_wrapper(void)
{
int n;
for(n=0;n<MAX_TIMERS;n++)
{
main_timer_list[n]=NULL;
}
my_jiffies=0;
num_irqs=0;
my_current=&act_cur;
pci_probe_dev=NULL;
for(n=0;n<MAX_IRQS;n++)
{
reg_irqs[n].handler=NULL;
reg_irqs[n].irq=-1;
}
drvs_num=0;
need_wakeup=0;
for(n=0;n<MAX_DRVS;n++)
m_drivers[n]=NULL;
}
/*------------------------------------------------------------------------*/
void handle_irqs(int irq)
{
int n;
// printk("handle irqs\n");
for(n=0;n<MAX_IRQS;n++)
{
if (reg_irqs[n].handler && (irq==reg_irqs[n].irq || irq==-1))
reg_irqs[n].handler(reg_irqs[n].irq,reg_irqs[n].data,NULL);
}
}
/*------------------------------------------------------------------------*/
void inc_jiffies(int n)
{
my_jiffies+=n;
}
/*------------------------------------------------------------------------*/
void do_all_timers(void)
{
int n;
for(n=0;n<MAX_TIMERS;n++)
{
if (main_timer_list[n] &&
main_timer_list[n]->function && main_timer_list[n]->expires)
{
void (*function)(unsigned long)=main_timer_list[n]->function;
unsigned long data=main_timer_list[n]->data;
main_timer_list[n]->expires=0;
main_timer_list[n]=NULL; // remove timer
// printk("do timer %i fn %p\n",n,function);
function(data);
}
}
}
/*------------------------------------------------------------------------*/
// Purpose: Remember thread procedure and data in global var
int my_kernel_thread(int (*handler)(void*), void* parm, int flags)
{
thread_handler=handler;
thread_parm=parm;
return 42; // PID :-)
}
/*------------------------------------------------------------------------*/
/* Device management
* As simple as possible, but as complete as necessary ...
*/
/*------------------------------------------------------------------------*/
/* calls probe function for hotplug (which does device matching), this is the
only link between usbcore and the registered device drivers! */
int my_device_add(struct device *dev)
{
int n,found=0;
// printk("drv_num %i %p %p\n",drvs_num,m_drivers[0]->probe,m_drivers[1]->probe);
if (dev->driver)
{
if (dev->driver->probe)
return dev->driver->probe(dev);
}
else
{
for(n=0;n<drvs_num;n++)
{
if (m_drivers[n]->probe)
{
dev->driver=m_drivers[n];
// printk("probe%i %p ",n,m_drivers[n]->probe);
if (m_drivers[n]->probe(dev) == 0)
{
// return 0;
found=1;
}
}
}
if (found) return 0;
}
dev->driver=NULL;
return -ENODEV;
}
/*------------------------------------------------------------------------*/
int my_driver_register(struct device_driver *driver)
{
if (drvs_num<MAX_DRVS)
{
// printk("driver_register %i: %p %p",drvs_num,driver,driver->probe);
m_drivers[drvs_num++]=driver;
return 0;
}
return -1;
}
/*------------------------------------------------------------------------*/
int my_device_unregister(struct device *dev)
{
if (dev->driver && dev->driver->remove)
dev->driver->remove(dev);
return 0;
}
/*------------------------------------------------------------------------*/
struct device *my_get_device(struct device *dev)
{
return NULL;
}
/*------------------------------------------------------------------------*/
void my_device_initialize(struct device *dev)
{
}
/*------------------------------------------------------------------------*/
void my_wake_up(void* p)
{
need_wakeup=1;
}
/*------------------------------------------------------------------------*/
/* wait until woken up (only one wait allowed!) */
int my_schedule_timeout(int x)
{
int wait=1;
x+=10; // safety
// printk("schedule_timeout %i\n",x);
while(x>0)
{
do_all_timers();
#ifndef HAVE_IRQS
handle_irqs(-1);
#endif
if (need_wakeup)
break;
wait_ms(wait);
inc_jiffies(wait);
x-=wait;
}
need_wakeup=0;
// printk("schedule DONE!!!!!!\n");
return x;
}
/*------------------------------------------------------------------------*/
void my_wait_for_completion(struct completion *x)
{
int n=1000;
// printk("wait for completion\n");
while(!x->done && (n>0))
{
do_all_timers();
#ifndef HAVE_IRQS
handle_irqs(-1);
#endif
wait_ms(10);
n--;
}
// printk("wait for completion done %i\n",x->done);
}
/*------------------------------------------------------------------------*/
// Helper for pci_module_init
/*------------------------------------------------------------------------*/
int my_pci_module_init(struct pci_driver *x)
{
struct pci_dev *dev=pci_probe_dev;
const struct pci_device_id *id=NULL;
if (!pci_probe_dev)
{
printk(KERN_ERR "PCI device not set!\n");
return 0;
}
x->probe(dev, id);
return 0;
}
/*------------------------------------------------------------------------*/
struct pci_dev *my_pci_find_slot(int a,int b)
{
return NULL;
}
/*------------------------------------------------------------------------*/
int my_request_irq(unsigned int irq,
int (*handler)(int,void *, struct pt_regs *),
unsigned long mode, const char *desc, void *data)
{
if (num_irqs<MAX_IRQS)
{
reg_irqs[num_irqs].handler=handler;
reg_irqs[num_irqs].irq=irq;
reg_irqs[num_irqs].data=data;
num_irqs++;
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
int my_free_irq(int irq, void* p)
{
/* No free... */
return 0;
}
/*------------------------------------------------------------------------*/

View file

@ -1,144 +0,0 @@
#include "../usb_wrapper.h"
#include "config.h"
// this is for the XPAD
extern unsigned char xpad_button_history[7];
// This is for the IR Remote control
extern unsigned int current_remote_key;
extern unsigned int current_remote_keydir;
// this is for the Keyboard
extern unsigned int current_keyboard_key;
unsigned char accepted_xremote [] = { 0x0b, 0xa6, 0xa7, 0xa9, 0xa8 ,0xd5,
0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf};
int risefall_xpad_BUTTON(unsigned char selected_Button) {
int temp;
int xpad_id;
extern int xpad_num;
// Section Keyboard
if (current_keyboard_key!=0) {
switch (selected_Button) {
case TRIGGER_XPAD_KEY_A :
if (current_keyboard_key == 0x28) {
current_keyboard_key=0;
return 1;
}
case TRIGGER_XPAD_KEY_B :
if (current_keyboard_key == 0x29) {
current_keyboard_key=0;
return 1;
}
case TRIGGER_XPAD_PAD_UP :
if (current_keyboard_key == 0x52) {
current_keyboard_key=0;
return 1;
}
case TRIGGER_XPAD_PAD_DOWN :
if (current_keyboard_key == 0x51) {
current_keyboard_key=0;
return 1;
}
case TRIGGER_XPAD_PAD_LEFT :
if (current_keyboard_key == 0x50) {
current_keyboard_key=0;
return 1;
}
case TRIGGER_XPAD_PAD_RIGHT :
if (current_keyboard_key == 0x4f) {
current_keyboard_key=0;
return 1;
}
}
}
// Section for IR Driver
temp = current_remote_keydir;
if ((temp&0x100)==0x100) {
int counter;
for (counter = 0; counter < (sizeof(accepted_xremote)) ; counter++) {
if (accepted_xremote[counter] == current_remote_key) {
temp &= 0xff;
current_remote_key &=0xff;
switch (selected_Button) {
case TRIGGER_XPAD_KEY_A :
if (current_remote_key == 0xb) return 1;
case TRIGGER_XPAD_PAD_UP :
if (current_remote_key == 0xa6) return 1;
case TRIGGER_XPAD_PAD_DOWN :
if (current_remote_key == 0xa7) return 1;
case TRIGGER_XPAD_PAD_LEFT :
if (current_remote_key == 0xa9) return 1;
case TRIGGER_XPAD_PAD_RIGHT :
if (current_remote_key == 0xa8) return 1;
case TRIGGER_XPAD_PAD_KEYSTROKE :
if (current_remote_key == 0xd5) return 0xd5;
if ((current_remote_key>0xc5)&(current_remote_key<0xd0)) return current_remote_key;
}
return 0;
}
}
}
for (xpad_id=0;xpad_id<xpad_num; xpad_id++) {
// We continue with normal XPAD operations
if (selected_Button < 6) {
unsigned char Button;
Button = XPAD_current[xpad_id].keys[selected_Button];
if ((Button>0x30)&&(xpad_button_history[selected_Button]==0)) {
// Button Rising Edge
xpad_button_history[selected_Button] = 1;
return 1;
}
if ((Button==0x00)&&(xpad_button_history[selected_Button]==1)) {
// Button Falling Edge
xpad_button_history[selected_Button] = 0;
return -1;
}
}
if ((selected_Button > 5) & (selected_Button < 10) ) {
unsigned char Buttonmask;
switch (selected_Button) {
case TRIGGER_XPAD_PAD_UP :
Buttonmask = XPAD_PAD_UP;
break;
case TRIGGER_XPAD_PAD_DOWN :
Buttonmask = XPAD_PAD_DOWN;
break;
case TRIGGER_XPAD_PAD_LEFT :
Buttonmask = XPAD_PAD_LEFT;
break;
case TRIGGER_XPAD_PAD_RIGHT :
Buttonmask = XPAD_PAD_RIGHT;
break;
}
// Rising Edge
if (((XPAD_current[xpad_id].pad&Buttonmask) != 0) & ((xpad_button_history[6]&Buttonmask) == 0)) {
xpad_button_history[6] ^= Buttonmask; // Flip the Bit
return 1;
}
// Falling Edge
if (((XPAD_current[xpad_id].pad&Buttonmask) == 0) & ((xpad_button_history[6]&Buttonmask) != 0)) {
xpad_button_history[6] ^= Buttonmask; // Flip the Bit
return -1;
}
}
}
return 0;
}

View file

@ -1,123 +0,0 @@
#include "../usb_wrapper.h"
#define keyboarddebug 0
#if keyboarddebug
extern int printe(const char *szFormat, ...);
int ycoffset = 0;
#endif
unsigned int current_keyboard_key;
struct usb_kbd_info {
struct urb *urb;
unsigned char kbd_pkt[8];
unsigned char old[8];
/*
struct input_dev dev;
struct usb_device *usbdev;
struct urb irq, led;
struct usb_ctrlrequest dr;
unsigned char leds, newleds;
char name[128];
int open;
*/
};
static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
{
struct usb_kbd_info *kbd = urb->context;
int i;
if (urb->status) return;
memcpy(kbd->kbd_pkt, urb->transfer_buffer, 8);
current_keyboard_key = kbd->kbd_pkt[2];
#if keyboarddebug
ycoffset += 15;
ycoffset = ycoffset % 600;
VIDEO_CURSOR_POSX=20;
VIDEO_CURSOR_POSY=ycoffset;
printe(" -%02x %02x %02x %02x %02x %02x\n",kbd->kbd_pkt[0],kbd->kbd_pkt[1],kbd->kbd_pkt[2],kbd->kbd_pkt[3],kbd->kbd_pkt[4],kbd->kbd_pkt[5]);
#endif
usb_submit_urb(urb,GFP_ATOMIC);
}
static int usb_kbd_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct usb_kbd_info *usbk;
int i, pipe, maxp;
char *buf;
usbk=(struct usb_kbd_info *)kmalloc(sizeof(struct usb_kbd_info),0);
if (!usbk) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
usbk->urb=urb;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
usbk->kbd_pkt, 8, usb_kbd_irq,
usbk, 8);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,usbk);
#if keyboarddebug
printe("USB Keyboard Connected\n");
#endif
}
static void usb_kbd_disconnect(struct usb_interface *intf)
{
struct usb_kbd_info *usbk = usb_get_intfdata (intf);
usbprintk("Keyboard disconnected\n ");
usb_unlink_urb(usbk->urb);
usb_free_urb(usbk->urb);
kfree(usbk);
}
static struct usb_device_id usb_kbd_id_table [] = {
{ USB_INTERFACE_INFO(3, 1, 1) },
{ } /* Terminating entry */
};
static struct usb_driver usb_kbd_driver = {
.owner = THIS_MODULE,
.name = "keyboard",
.probe = usb_kbd_probe,
.disconnect = usb_kbd_disconnect,
.id_table = usb_kbd_id_table,
};
void UsbKeyBoardInit(void)
{
//current_remote_key=0;
//sbprintk("Keyboard probe %p ",xremote_probe);
if (usb_register(&usb_kbd_driver) < 0) {
#if keyboarddebug
printe("Unable to register Keyboard driver");
#endif
return;
}
}
void UsbKeyBoardRemove(void) {
usb_deregister(&usb_kbd_driver);
}

View file

@ -1,65 +0,0 @@
/*
* Interface calls to BIOS
*
* 2003-06-21 Georg Acher (georg@acher.org)
*
*/
#include "boot.h"
#include <stdarg.h>
#include "video.h"
/*------------------------------------------------------------------------*/
// Output window for USB messages
int usb_curs_x=0;
int usb_curs_y=0;
void zxprintf(char* fmt, ...)
{
va_list ap;
char buffer[1024];
int tmp_x, tmp_y;
tmp_x=VIDEO_CURSOR_POSX;
tmp_y=VIDEO_CURSOR_POSY;
VIDEO_CURSOR_POSX=usb_curs_x;
VIDEO_CURSOR_POSY=usb_curs_y;
if ((VIDEO_CURSOR_POSY==0) || (VIDEO_CURSOR_POSY > (vmode.height -16)))
{
BootVideoClearScreen(&jpegBackdrop, 3*vmode.height/4,
vmode.height);
VIDEO_CURSOR_POSY=3*vmode.height/4;
}
va_start(ap, fmt);
vsprintf(buffer,fmt,ap);
//printk(buffer);
va_end(ap);
usb_curs_x=VIDEO_CURSOR_POSX;
usb_curs_y=VIDEO_CURSOR_POSY;
VIDEO_CURSOR_POSX=tmp_x;
VIDEO_CURSOR_POSY=tmp_y;
}
/*------------------------------------------------------------------------*/
int zxsnprintf(char *buffer, size_t s, char* fmt, ...)
{
va_list ap;
int x;
va_start(ap, fmt);
x=vsprintf(buffer,fmt,ap);
va_end(ap);
return x;
}
/*------------------------------------------------------------------------*/
int zxsprintf(char *buffer, char* fmt, ...)
{
va_list ap;
int x;
va_start(ap, fmt);
x=vsprintf(buffer,fmt,ap);
va_end(ap);
return x;
}
/*------------------------------------------------------------------------*/

View file

@ -1,175 +0,0 @@
/*
* Simple XPAD driver for XBOX
*
* (c) 2003-07-04, Georg Acher (georg@acher.org)
*
* Inspired by linux/drivers/usb/input/xpad.c
* by Marko Friedemann <mfr@bmx-chemnitz.de>
*
*/
#include "../usb_wrapper.h"
#include "config.h"
// history for the Rising - falling events
unsigned char xpad_button_history[7];
/* Stores time and XPAD state */
struct xpad_data XPAD_current[4];
struct xpad_data XPAD_last[4];
struct xpad_info
{
struct urb *urb;
int num;
unsigned char data[32];
};
int xpad_num=0;
/*------------------------------------------------------------------------*/
static void xpad_irq(struct urb *urb, struct pt_regs *regs)
{
struct xpad_info *xpi = urb->context;
unsigned char* data= urb->transfer_buffer;
struct xpad_data *xp=&XPAD_current[xpi->num];
struct xpad_data *xpo=&XPAD_last[xpi->num];
if (xpi->num<0 || xpi->num>3)
return;
memcpy(xpo,xp,sizeof(struct xpad_data));
xp->stick_left_x=(short) (((short)data[13] << 8) | data[12]);
xp->stick_left_y=(short) (((short)data[15] << 8) | data[14]);
xp->stick_right_x=(short) (((short)data[17] << 8) | data[16]);
xp->stick_right_y=(short) (((short)data[19] << 8) | data[18]);
xp->trig_left= data[10];
xp->trig_right= data[11];
xp->pad = data[2]&0xf;
xp->state = (data[2]>>4)&0xf;
xp->keys[0] = data[4]; // a
xp->keys[1] = data[5]; // b
xp->keys[2] = data[6]; // x
xp->keys[3] = data[7]; // y
xp->keys[4] = data[8]; // black
xp->keys[5] = data[9]; // white
xp->timestamp=jiffies; // FIXME: A more uniform flowing time would be better...
usb_submit_urb(urb,GFP_ATOMIC);
}
/*------------------------------------------------------------------------*/
static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct xpad_info *xpi;
xpi=kmalloc(sizeof(struct xpad_info),GFP_KERNEL);
if (!xpi) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
xpi->urb=urb;
xpi->num=xpad_num;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpi->data, 32, xpad_irq,
xpi, 32);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,xpi);
usbprintk("XPAD #%i connected\n",xpad_num);
#ifdef XPAD_VIBRA_STARTUP
{
// Brum Brum
char data1[6]={0,6,0,120,0,120};
char data2[6]={0,6,0,0,0,0};
int dummy;
usb_bulk_msg(udev, usb_sndbulkpipe(udev,2),
data1, 6, &dummy, 500);
wait_ms(500);
usb_bulk_msg(udev, usb_sndbulkpipe(udev,2),
data2, 6, &dummy, 500);
}
#endif
xpad_num++;
return 0;
}
/*------------------------------------------------------------------------*/
static void xpad_disconnect(struct usb_interface *intf)
{
struct xpad_info *xpi=usb_get_intfdata (intf);
usbprintk("XPAD disconnected\n ");
usb_unlink_urb(xpi->urb);
usb_free_urb(xpi->urb);
kfree(xpi);
xpad_num--;
}
/*------------------------------------------------------------------------*/
static struct usb_device_id xpad_ids [] = {
{ USB_DEVICE(0x044f, 0x0f07) },//Thrustmaster, Inc. Controller
{ USB_DEVICE(0x045e, 0x0202) },//Microsoft Xbox Controller
{ USB_DEVICE(0x045e, 0x0285) },//Microsoft Xbox Controller S
{ USB_DEVICE(0x045e, 0x0289) },//Microsoft Xbox Controller S
{ USB_DEVICE(0x046d, 0xca88) },//Logitech Compact Controller for Xbox
{ USB_DEVICE(0x05fd, 0x1007) },//???Mad Catz Controller???
{ USB_DEVICE(0x05fd, 0x107a) },//InterAct PowerPad Pro
{ USB_DEVICE(0x0738, 0x4516) },//Mad Catz Control Pad
{ USB_DEVICE(0x0738, 0x4522) },//Mad Catz LumiCON
{ USB_DEVICE(0x0738, 0x4526) },//Mad Catz Control Pad Pro
{ USB_DEVICE(0x0738, 0x4536) },//Mad Catz MicroCON
{ USB_DEVICE(0x0738, 0x4556) },//Mad Catz Lynx Wireless Controller
{ USB_DEVICE(0x0c12, 0x9902) },//HAMA VibraX - *FAULTY HARDWARE*
{ USB_DEVICE(0x0e4c, 0x1097) },//Radica Gamester Controller
{ USB_DEVICE(0x0e4c, 0x2390) },//Radica Games Jtech Controller
{ USB_DEVICE(0x0e6f, 0x0003) },//Logic3 Freebird wireless Controller
{ USB_DEVICE(0x0e6f, 0x0005) },//Eclipse wireless Controlle
{ USB_DEVICE(0x0f30, 0x0202) },//Joytech Advanced Controller
{ USB_DEVICE(0xffff, 0xffff) },//Chinese-made Xbox Controller
{ USB_DEVICE(0x0000, 0x0000) }, // nothing detected - FAIL
{ } /* Terminating entry */
};
static struct usb_driver xpad_driver = {
.owner = THIS_MODULE,
.name = "XPAD",
.probe = xpad_probe,
.disconnect = xpad_disconnect,
.id_table = xpad_ids,
};
/*------------------------------------------------------------------------*/
void XPADInit(void)
{
int n;
for(n=0;n<4;n++)
{
memset(XPAD_current,0, sizeof(struct xpad_data));
memset(XPAD_last,0, sizeof(struct xpad_data));
}
memset(&xpad_button_history,0x0,sizeof(xpad_button_history));
usbprintk("XPAD probe %p ",xpad_probe);
if (usb_register(&xpad_driver) < 0) {
err("Unable to register XPAD driver");
return;
}
}
/*------------------------------------------------------------------------*/
void XPADRemove(void) {
usb_deregister(&xpad_driver);
}
/*------------------------------------------------------------------------*/

View file

@ -1,164 +0,0 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* $Id: xremote.c,v 1.2 2003/09/15 20:02:12 hamtitampti Exp $
*
* Copyright (c) 2002 Steven Toth <steve@toth.demon.co.uk>
*
* XBOX DVD dongle infrared device driver for the input driver suite.
*
* This work was derived from the usbkbd.c kernel module.
*
* History:
*
* 2002_08_31 - 0.1 - Initial release
* 2002_09_02 - 0.2 - Added IOCTL support enabling user space administration
* of the translation matrix.
*
*/
#include "../usb_wrapper.h"
unsigned int last_remote_key;
unsigned int last_remote_keydir;
unsigned int current_remote_key;
unsigned int current_remote_keydir;
unsigned int Last_remote_keystroke;
struct xremote_info
{
struct urb *urb;
unsigned char irpkt[8];
};
/* USB callback completion handler
* Code in transfer_buffer is received as six unsigned chars
* Example PLAY=00 06 ea 0a 40 00
* The command is located in byte[2], the rest are ignored.
* Key position is byte[4] bit0 (7-0 format) 0=down, 1=up
* All other bits are unknown / now required.
*/
static void xremote_irq(struct urb *urb, struct pt_regs *regs)
{
struct xremote_info *xri = urb->context;
if (urb->status) return;
if (urb->actual_length < 6) return;
/* Messy/unnecessary, fix this */
memcpy(xri->irpkt, urb->transfer_buffer, 6);
last_remote_key = current_remote_key;
last_remote_keydir = current_remote_keydir;
/* Set the key action based in the sent action */
current_remote_key = (xri->irpkt[2] & 0xff);
current_remote_keydir = (xri->irpkt[4] & 0xff);
Last_remote_keystroke = (xri->irpkt[4] & 0xff);
Last_remote_keystroke += (xri->irpkt[5] & 0xff ) << 8;
if (Last_remote_keystroke > 0x41) current_remote_keydir |= 0x100;
usb_submit_urb(urb,GFP_ATOMIC);
}
static int xremote_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct urb *urb;
struct usb_device *udev = interface_to_usbdev (intf);
struct usb_endpoint_descriptor *ep_irq_in;
struct usb_endpoint_descriptor *ep_irq_out;
struct xremote_info *xri;
int i, pipe, maxp;
char *buf;
xri=(struct xremote_info *)kmalloc(sizeof(struct xremote_info),0);
if (!xri) return -1;
urb=usb_alloc_urb(0,0);
if (!urb) return -1;
xri->urb=urb;
ep_irq_in = &intf->altsetting[0].endpoint[0].desc;
usb_fill_int_urb(urb, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xri->irpkt, 8, xremote_irq,
xri, 8);
usb_submit_urb(urb,GFP_ATOMIC);
usb_set_intfdata(intf,xri);
usbprintk("DVD Remote connected\n");
return 0;
}
static void xremote_disconnect(struct usb_interface *intf)
{
struct xremote_info *xri = usb_get_intfdata (intf);
usbprintk("DVD Remote disconnected\n ");
usb_unlink_urb(xri->urb);
usb_free_urb(xri->urb);
kfree(xri);
}
static struct usb_device_id xremote_id_table [] = {
{ USB_DEVICE(0x045e, 0x0284) }, /* Microsoft, DVD dongle */
{ } /* Terminating entry */
};
static struct usb_driver xremote_driver = {
.owner = THIS_MODULE,
.name = "XRemote",
.probe = xremote_probe,
.disconnect = xremote_disconnect,
.id_table = xremote_id_table,
};
void XRemoteInit(void)
{
current_remote_key=0;
usbprintk("XRemote probe %p ",xremote_probe);
if (usb_register(&xremote_driver) < 0) {
err("Unable to register XRemote driver");
return;
}
}
void XRemoteRemove(void) {
usb_deregister(&xremote_driver);
}
int isRemoteKeyEvent(unsigned int button)
{
int rv = 0;
if ( current_remote_key == button )
{
rv = current_remote_keydir;
// got the event, so disable the key
current_remote_key = 0;
}
return rv;
}

View file

@ -1,143 +0,0 @@
/* Tiny module to test USB encapsulation
* (c) 2003, Georg Acher, georg@acher.org
*/
#include <linux/module.h>
#include <linux/socket.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <asm/hardirq.h>
#include <linux/pci.h>
/*------------------------------------------------------------------------*/
void my_wait_ms(unsigned int ms)
{
// if(!in_interrupt()) {
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout(1 + ms * HZ / 1000);
// }
// else
// mdelay(ms);
}
/*------------------------------------------------------------------------*/
void my_mdelay(int x)
{
mdelay(x);
}
/*------------------------------------------------------------------------*/
void my_udelay(int x)
{
udelay(x);
}
/*------------------------------------------------------------------------*/
/*------------------------------------------------------------------------*/
void* zxmalloc(size_t s)
{
return kmalloc(s,GFP_DMA);
}
/*------------------------------------------------------------------------*/
void zxfree(void* x)
{
kfree(x);
}
/*------------------------------------------------------------------------*/
void zxprintf(char* fmt, ...)
{
va_list ap;
char buffer[1024];
va_start(ap, fmt);
vsnprintf(buffer,1024,fmt,ap);
usbprintk(buffer);
va_end(ap);
}
/*------------------------------------------------------------------------*/
int zxsnprintf(char *buffer, size_t s, char* fmt, ...)
{
va_list ap;
int x;
va_start(ap, fmt);
x=vsnprintf(buffer,s,fmt,ap);
va_end(ap);
return x;
}
/*------------------------------------------------------------------------*/
int zxsprintf(char *buffer, char* fmt, ...)
{
va_list ap;
int x;
va_start(ap, fmt);
x=vsprintf(buffer,fmt,ap);
va_end(ap);
return x;
}
static DECLARE_COMPLETION(testd_exited);
static pid_t testd_pid=0;
void test_usb_init(void);
void test_usb_events(void);
static int test_thread(void *x)
{
reparent_to_init();
/* Setup a nice name */
strcpy(current->comm, "testd_usb");
usbprintk("Thread started\n");
test_usb_init();
do {
test_usb_events();
my_wait_ms(50);
} while (!signal_pending(current));
usbprintk("hub_thread exiting\n");
complete_and_exit(&testd_exited, 0);
}
/*------------------------------------------------------------------------*/
void *ohci_base;
static int __init test_init (void)
{
struct pci_dev *dev = NULL;
unsigned long resource, len;
usbprintk("module init\n");
dev =pci_find_device (0x1045,0xc861, dev);
pci_enable_device (dev);
resource = pci_resource_start (dev, 0);
len = pci_resource_len (dev, 0);
ohci_base = ioremap_nocache (resource, len);
usbprintk("base %p, len %i\n",ohci_base,len);
pci_set_master (dev);
testd_pid = kernel_thread(test_thread, NULL,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
return 0;
}
/*------------------------------------------------------------------------*/
static void __exit test_cleanup (void)
{
usbprintk("test_cleanup start\n");
if (testd_pid)
{
int ret;
ret = kill_proc(testd_pid, SIGKILL, 1);
my_wait_ms(1000);
// wait_for_completion(&testd_exited);
}
usbprintk("test_cleanup\n");
}
/*------------------------------------------------------------------------*/
MODULE_LICENSE("GPL");
module_init (test_init);
module_exit (test_cleanup);

View file

@ -1,6 +0,0 @@
#include "linux_wrapper.h"
#define __KERNEL__
#undef CONFIG_PCI
#define CONFIG_PCI
#include "linux/usb.h"

View file

@ -1,522 +0,0 @@
/*
* video-related stuff
* 2004-03-03 dmp@davidmpye.dyndns.org Synced with kernel fb driver, added proper focus support etc
* 2003-02-02 andy@warmcat.com Major reshuffle, threw out tons of unnecessary init
Made a good start on separating the video mode from the AV cable
Consolidated init tables into a big struct (see boot.h)
* 2002-12-04 andy@warmcat.com Video now working :-)
*/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "boot.h"
#include "BootEEPROM.h"
#include "config.h"
#include "BootVideo.h"
#include "video.h"
#include "memory_layout.h"
#include "VideoInitialization.h"
#include "BootVgaInitialization.h"
#include "encoder.h"
#include "xcalibur.h"
#include "xcalibur-regs.h"
void DetectVideoEncoder(void) {
if (I2CTransmitByteGetReturn(0x45,0x00) != ERR_I2C_ERROR_BUS) video_encoder = ENCODER_CONEXANT;
else if (I2CTransmitByteGetReturn(0x6a,0x00) != ERR_I2C_ERROR_BUS) video_encoder = ENCODER_FOCUS;
else video_encoder = ENCODER_XCALIBUR;
}
char *VideoEncoderName(void) {
char *focus_name="Focus";
char *conexant_name="Conexant";
char *xcalibur_name="XCalibur";
char *unknown_name="Unknown";
switch (video_encoder) {
case ENCODER_CONEXANT:
return conexant_name;
case ENCODER_FOCUS:
return focus_name;
case ENCODER_XCALIBUR:
return xcalibur_name;
default:
return unknown_name;
}
}
char *AvCableName(void) {
char *composite_name="Composite";
char *svideo_name="SVideo";
char *rgb_name="RGB SCART";
char *hdtv_name="HDTV";
char *vga_name="VGA";
char *vgasog_name="VGA SoG";
char *unknown_name="Unknown";
xbox_av_type av_type = DetectAvType();
switch (av_type) {
case AV_SCART_RGB:
return rgb_name;
case AV_SVIDEO:
return svideo_name;
case AV_VGA_SOG:
return vgasog_name;
case AV_HDTV:
return hdtv_name;
case AV_COMPOSITE:
return composite_name;
case AV_VGA:
return vga_name;
default:
return unknown_name;
}
}
void BootVgaInitializationKernelNG(CURRENT_VIDEO_MODE_DETAILS * pvmode) {
xbox_tv_encoding tv_encoding;
xbox_av_type av_type;
BYTE b;
RIVA_HW_INST riva;
struct riva_regs newmode;
int encoder_ok = 0;
int i=0;
GPU_PARAMETER gpu;
xbox_video_mode encoder_mode;
tv_encoding = DetectVideoStd();
DetectVideoEncoder();
// Dump to global variable
VIDEO_AV_MODE=I2CTransmitByteGetReturn(0x10, 0x04);
av_type = DetectAvType();
gpu.av_type = av_type;
memset((void *)pvmode,0,sizeof(CURRENT_VIDEO_MODE_DETAILS));
//Focus driver (presumably XLB also) doesnt do widescreen yet - only blackscreens otherwise.
if(((BYTE *)&eeprom)[0x96]&0x01 && video_encoder == ENCODER_CONEXANT) { // 16:9 widescreen TV
pvmode->m_nVideoModeIndex=VIDEO_MODE_1024x576;
} else { // 4:3 TV
pvmode->m_nVideoModeIndex=VIDEO_PREFERRED_MODE;
}
pvmode->m_pbBaseAddressVideo=(BYTE *)0xfd000000;
pvmode->m_fForceEncoderLumaAndChromaToZeroInitially=1;
// If the client hasn't set the frame buffer start address, assume
// it should be at 4M from the end of RAM.
pvmode->m_dwFrameBufferStart = FB_START;
(*(unsigned int*)0xFD600800) = (FB_START & 0x0fffffff);
pvmode->m_bAvPack=I2CTransmitByteGetReturn(0x10, 0x04);
pvmode->m_pbBaseAddressVideo=(BYTE *)0xfd000000;
pvmode->m_fForceEncoderLumaAndChromaToZeroInitially=1;
pvmode->m_bBPP = 32;
b=I2CTransmitByteGetReturn(0x54, 0x5A); // the eeprom defines the TV standard for the box
// The values for hoc and voc are stolen from nvtv small mode
if(b != 0x40) {
pvmode->hoc = 13.44;
pvmode->voc = 14.24;
} else {
pvmode->hoc = 15.11;
pvmode->voc = 14.81;
}
pvmode->hoc /= 100.0;
pvmode->voc /= 100.0;
mapNvMem(&riva,pvmode->m_pbBaseAddressVideo);
unlockCrtNv(&riva,0);
if (xbox_ram == 128) {
MMIO_H_OUT32(riva.PFB ,0,0x200,0x03070103);
} else {
MMIO_H_OUT32(riva.PFB ,0,0x200,0x03070003);
}
MMIO_H_OUT32 (riva.PCRTC, 0, 0x800, pvmode->m_dwFrameBufferStart);
IoOutputByte(0x80d3, 5); // Kill all video out using an ACPI control pin
if (video_encoder==ENCODER_XCALIBUR) {
MMIO_H_OUT32(riva.PRAMDAC,0,0x880,0x21101100);
//Leave GPU in YUV for Xcalibur
MMIO_H_OUT32(riva.PRAMDAC,0,0x630,0x2);
MMIO_H_OUT32(riva.PRAMDAC,0,0x84c,0x00801080);
MMIO_H_OUT32(riva.PRAMDAC,0,0x8c4,0x40801080);
}
else {
MMIO_H_OUT32(riva.PRAMDAC,0,0x880,0);
}
MMIO_H_OUT32(riva.PRAMDAC,0,0x884,0x0);
MMIO_H_OUT32(riva.PRAMDAC,0,0x888,0x0);
MMIO_H_OUT32(riva.PRAMDAC,0,0x88c,0x10001000);
MMIO_H_OUT32(riva.PRAMDAC,0,0x890,0x10000000);
MMIO_H_OUT32(riva.PRAMDAC,0,0x894,0x10000000);
MMIO_H_OUT32(riva.PRAMDAC,0,0x898,0x10000000);
MMIO_H_OUT32(riva.PRAMDAC,0,0x89c,0x10000000);
writeCrtNv (&riva, 0, 0x14, 0x00);
writeCrtNv (&riva, 0, 0x17, 0xe3); // Set CRTC mode register
writeCrtNv (&riva, 0, 0x19, 0x10); // ?
writeCrtNv (&riva, 0, 0x1b, 0x05); // arbitration0
writeCrtNv (&riva, 0, 0x22, 0xff); // ?
writeCrtNv (&riva, 0, 0x33, 0x11); // ?
if((av_type == AV_VGA) || (av_type == AV_VGA_SOG) || (av_type == AV_HDTV)) {
unsigned char pll_int;
if (av_type == AV_HDTV) {
xbox_hdtv_mode hdtv_mode = HDTV_480p;
//Only 480p supported at present
/*if (video_mode->yres > 800) {
hdtv_mode = HDTV_1080i;
}
else if (video_mode->yres > 600) {
hdtv_mode = HDTV_720p;
}*/
// Settings for 720x480@60Hz (480p)
pvmode->width=720;
pvmode->height=480;
pvmode->xmargin=0;
pvmode->ymargin=0;
/* HDTV uses hardcoded settings for these - these are the
* correct ones for 480p */
gpu.xres = pvmode->width;
gpu.nvhstart = 738;
gpu.nvhtotal = 858;
gpu.yres = pvmode->height;
gpu.nvvstart = 489;
gpu.nvvtotal = 525;
gpu.pixelDepth = (32 + 1) / 8;
gpu.crtchdispend = pvmode->width;
gpu.crtcvstart = gpu.nvvstart;
gpu.crtcvtotal = gpu.nvvtotal;
pll_int = (unsigned char)((double)27027 * 6.0 / 13.5e3 + 0.5);
if (video_encoder == ENCODER_CONEXANT)
encoder_ok = conexant_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode);
else if (video_encoder == ENCODER_FOCUS)
encoder_ok = focus_calc_hdtv_mode(hdtv_mode, pll_int, newmode.encoder_mode);
}
else {
//VGA or VGA_SOG
// Settings for 800x600@56Hz, 35 kHz HSync
pvmode->width=800;
pvmode->height=600;
pvmode->xmargin=20;
pvmode->ymargin=20;
gpu.xres = pvmode->width;
gpu.nvhstart = 900;
gpu.nvhtotal = 1028;
gpu.yres = pvmode->height;
gpu.nvvstart = 614;
gpu.nvvtotal = 630;
gpu.pixelDepth = (32 + 1) / 8;
gpu.crtchdispend = pvmode->width;
gpu.crtcvstart = gpu.nvvstart;
gpu.crtcvtotal = gpu.nvvtotal;
pll_int = (unsigned char)((double)36000 * 6.0 / 13.5e3 + 0.5);
if (video_encoder == ENCODER_CONEXANT)
encoder_ok = conexant_calc_vga_mode(av_type, pll_int, newmode.encoder_mode);
else if (video_encoder == ENCODER_FOCUS);
//No focus VGA functions as yet
}
}
else {
/* All other cable types - normal SDTV */
switch(pvmode->m_nVideoModeIndex) {
case VIDEO_MODE_640x480:
pvmode->width=640;
pvmode->height=480;
pvmode->xmargin=0;
pvmode->ymargin=0;
break;
case VIDEO_MODE_640x576:
pvmode->width=640;
pvmode->height=576;
pvmode->xmargin=40; // pixels
pvmode->ymargin=40; // lines
break;
case VIDEO_MODE_720x576:
pvmode->width=720;
pvmode->height=576;
pvmode->xmargin=40; // pixels
pvmode->ymargin=40; // lines
break;
case VIDEO_MODE_800x600: // 800x600
pvmode->width=800;
pvmode->height=600;
pvmode->xmargin=20;
pvmode->ymargin=20; // lines
break;
case VIDEO_MODE_1024x576: // 1024x576
pvmode->width=1024;
pvmode->height=576;
pvmode->xmargin=20;
pvmode->ymargin=20; // lines
break;
}
encoder_mode.xres = pvmode->width;
encoder_mode.yres = pvmode->height;
encoder_mode.tv_encoding = tv_encoding;
encoder_mode.bpp = 32;
encoder_mode.hoc = pvmode->hoc;
encoder_mode.voc = pvmode->voc;
encoder_mode.av_type = av_type;
encoder_mode.tv_encoding = tv_encoding;
if (video_encoder == ENCODER_CONEXANT) {
encoder_ok = conexant_calc_mode(&encoder_mode, &newmode);
}
else if (video_encoder == ENCODER_FOCUS) {
encoder_ok = focus_calc_mode(&encoder_mode, &newmode);
}
else if (video_encoder == ENCODER_XCALIBUR) {
encoder_ok = xcalibur_calc_mode(&encoder_mode, &newmode, tv_encoding);
}
gpu.xres = pvmode->width;
gpu.nvhstart = newmode.ext.hsyncstart;
gpu.nvhtotal = newmode.ext.htotal;
gpu.yres = pvmode->height;
gpu.nvvstart = newmode.ext.vsyncstart;
gpu.nvvtotal = newmode.ext.vtotal;
gpu.pixelDepth = (32 + 1) / 8;
gpu.crtchdispend = pvmode->width;
gpu.crtcvstart = newmode.ext.vsyncstart;
gpu.crtcvtotal = newmode.ext.vtotal;
}
if (encoder_ok) {
//Set up the GPU
SetGPURegister(&gpu, pvmode->m_pbBaseAddressVideo);
//Load registers into chip
if (video_encoder == ENCODER_CONEXANT) {
int n1=0;
I2CWriteBytetoRegister(0x45,0xc4, 0x00); // EN_OUT = 1
// Conexant init (starts at register 0x2e)
n1=0;
for(i=0x2e;i<0x100;i+=2) {
switch(i) {
case 0x6c: // reset
I2CWriteBytetoRegister(0x45,i, newmode.encoder_mode[n1] & 0x7f);
break;
case 0xc4: // EN_OUT
I2CWriteBytetoRegister(0x45,i, newmode.encoder_mode[n1] & 0xfe);
break;
case 0xb8: // autoconfig
break;
default:
I2CWriteBytetoRegister(0x45,i, newmode.encoder_mode[n1]);
break;
}
n1++;
wait_us(800);
}
// Timing Reset
b=I2CTransmitByteGetReturn(0x45,0x6c) & (0x7f);
I2CWriteBytetoRegister(0x45, 0x6c, 0x80|b);
b=I2CTransmitByteGetReturn(0x45,0xc4) & (0xfe);
I2CWriteBytetoRegister(0x45, 0xc4, 0x01|b); // EN_OUT = 1
}
else if (video_encoder == ENCODER_FOCUS) {
for (i=0; i<0xc4; ++i) {
I2CWriteBytetoRegister(0x6a, i, newmode.encoder_mode[i]);
wait_us(800);
}
}
else if (video_encoder == ENCODER_XCALIBUR) {
//Xlb init
ReadfromSMBus(0x70,4,4,&i);
WriteToSMBus(0x70,4,4,0x0F000000);
ReadfromSMBus(0x70,0,4,&i);
WriteToSMBus(0x70,0,4,0x00000000);
MMIO_H_OUT32(riva.PRAMDAC, 0, 0x630, 0x2);
if ( tv_encoding == TV_ENC_PALBDGHI) {
/* Encoder registers */
for (i=0; i<(sizeof(xcal_video_register_sequence)); i++) {
WriteToSMBus(0x70,xcal_video_register_sequence[i],4,xcal_composite_pal[i]);
wait_us(50);
}
}
else {
//NTSC
/* Encoder registers */
for (i=0; i<(sizeof(xcal_video_register_sequence)); i++) {
WriteToSMBus(0x70,xcal_video_register_sequence[i],4,xcal_composite_ntsc[i]);
wait_us(50);
}
}
}
}
NVDisablePalette (&riva, 0);
writeCrtNv (&riva, 0, 0x44, 0x03);
NVInitGrSeq(&riva);
writeCrtNv (&riva, 0, 0x44, 0x00);
NVInitAttr(&riva,0);
IoOutputByte(0x80d8, 4); // ACPI IO thing seen in kernel, set to 4
IoOutputByte(0x80d6, 5); // ACPI IO thing seen in kernel, set to 4 or 5
NVVertIntrEnabled (&riva,0);
NVSetFBStart (&riva, 0, pvmode->m_dwFrameBufferStart);
IoOutputByte(0x80d3, 4); // ACPI IO video enable REQUIRED <-- particularly crucial to get composite out
// We dimm the Video OFF - focus video is implicitly disabled.
if (video_encoder == ENCODER_CONEXANT) {
I2CTransmitWord(0x45, (0xa8<<8)|0);
I2CTransmitWord(0x45, (0xaa<<8)|0);
I2CTransmitWord(0x45, (0xac<<8)|0);
}
NVWriteSeq(&riva, 0x01, 0x01); /* reenable display */
if (video_encoder == ENCODER_CONEXANT) {
I2CWriteBytetoRegister(0x45, 0xA8, 0x81);
I2CWriteBytetoRegister(0x45, 0xAA, 0x49);
I2CWriteBytetoRegister(0x45, 0xAC, 0x8C);
}
else if (video_encoder == ENCODER_FOCUS) {
b = I2CTransmitByteGetReturn(0x6a,0x0c);
b &= ~0x01;
I2CWriteBytetoRegister(0x6a,0x0c,b);
b = I2CTransmitByteGetReturn(0x6a,0x0d);
I2CWriteBytetoRegister(0x6a,0x0d,b);
}
else if (video_encoder == ENCODER_XCALIBUR) {
//Video output is already on.
}
}
static void NVSetFBStart (RIVA_HW_INST *riva, int head, DWORD dwFBStart) {
MMIO_H_OUT32 (riva->PCRTC, head, 0x8000, dwFBStart);
MMIO_H_OUT32 (riva->PMC, head, 0x8000, dwFBStart);
}
static void NVVertIntrEnabled (RIVA_HW_INST *riva, int head)
{
MMIO_H_OUT32 (riva->PCRTC, head, 0x140, 0x1);
MMIO_H_OUT32 (riva->PCRTC, head, 0x100, 0x1);
MMIO_H_OUT32 (riva->PCRTC, head, 0x140, 1);
MMIO_H_OUT32 (riva->PMC, head, 0x140, 0x1);
MMIO_H_OUT32 (riva->PMC, head, 0x100, 0x1);
MMIO_H_OUT32 (riva->PMC, head, 0x140, 1);
}
static inline void unlockCrtNv (RIVA_HW_INST *riva, int head)
{
writeCrtNv (riva, head, 0x1f, 0x57); /* unlock extended registers */
}
static inline void lockCrtNv (RIVA_HW_INST *riva, int head)
{
writeCrtNv (riva, head, 0x1f, 0x99); /* lock extended registers */
}
static void writeCrtNv (RIVA_HW_INST *riva, int head, int reg, BYTE val)
{
VGA_WR08(riva->PCIO, CRT_INDEX(head), reg);
VGA_WR08(riva->PCIO, CRT_DATA(head), val);
}
static void mapNvMem (RIVA_HW_INST *riva, BYTE *IOAddress)
{
riva->PMC = IOAddress+0x000000;
riva->PFB = IOAddress+0x100000;
riva->PEXTDEV = IOAddress+0x101000;
riva->PCRTC = IOAddress+0x600000;
riva->PCIO = riva->PCRTC + 0x1000;
riva->PVIO = IOAddress+0x0C0000;
riva->PRAMDAC = IOAddress+0x680000;
riva->PDIO = riva->PRAMDAC + 0x1000;
riva->PVIDEO = IOAddress+0x008000;
riva->PTIMER = IOAddress+0x009000;
}
static void NVDisablePalette (RIVA_HW_INST *riva, int head)
{
volatile CARD8 tmp;
tmp = VGA_RD08(riva->PCIO + head * HEAD, VGA_IOBASE_COLOR + VGA_IN_STAT_1_OFFSET);
VGA_WR08(riva->PCIO + head * HEAD, VGA_ATTR_INDEX, 0x20);
}
static void NVWriteSeq(RIVA_HW_INST *riva, CARD8 index, CARD8 value)
{
VGA_WR08(riva->PVIO, VGA_SEQ_INDEX, index);
VGA_WR08(riva->PVIO, VGA_SEQ_DATA, value);
}
static void NVWriteGr(RIVA_HW_INST *riva, CARD8 index, CARD8 value)
{
VGA_WR08(riva->PVIO, VGA_GRAPH_INDEX, index);
VGA_WR08(riva->PVIO, VGA_GRAPH_DATA, value);
}
static void NVInitGrSeq (RIVA_HW_INST *riva)
{
NVWriteSeq(riva, 0x00, 0x03);
NVWriteSeq(riva, 0x01, 0x21);
NVWriteSeq(riva, 0x02, 0x0f);
NVWriteSeq(riva, 0x03, 0x00);
NVWriteSeq(riva, 0x04, 0x06);
NVWriteGr(riva, 0x00, 0x00);
NVWriteGr(riva, 0x01, 0x00);
NVWriteGr(riva, 0x02, 0x00);
NVWriteGr(riva, 0x03, 0x00);
NVWriteGr(riva, 0x04, 0x00); /* depth != 1 */
NVWriteGr(riva, 0x05, 0x40); /* depth != 1 && depth != 4 */
NVWriteGr(riva, 0x06, 0x05);
NVWriteGr(riva, 0x07, 0x0f);
NVWriteGr(riva, 0x08, 0xff);
}
static void NVWriteAttr(RIVA_HW_INST *riva, int head, CARD8 index, CARD8 value)
{
MMIO_H_OUT8(riva->PCIO, head, VGA_ATTR_INDEX, index);
MMIO_H_OUT8(riva->PCIO, head, VGA_ATTR_DATA_W, value);
}
static void NVInitAttr (RIVA_HW_INST *riva, int head)
{
NVWriteAttr(riva,0, 0, 0x01);
NVWriteAttr(riva,0, 1, 0x02);
NVWriteAttr(riva,0, 2, 0x03);
NVWriteAttr(riva,0, 3, 0x04);
NVWriteAttr(riva,0, 4, 0x05);
NVWriteAttr(riva,0, 5, 0x06);
NVWriteAttr(riva,0, 6, 0x07);
NVWriteAttr(riva,0, 7, 0x08);
NVWriteAttr(riva,0, 8, 0x09);
NVWriteAttr(riva,0, 9, 0x0a);
NVWriteAttr(riva,0, 10, 0x0b);
NVWriteAttr(riva,0, 11, 0x0c);
NVWriteAttr(riva,0, 12, 0x0d);
NVWriteAttr(riva,0, 13, 0x0e);
NVWriteAttr(riva,0, 14, 0x0f);
NVWriteAttr(riva,0, 15, 0x01);
NVWriteAttr(riva,0, 16, 0x4a);
NVWriteAttr(riva,0, 17, 0x0f);
NVWriteAttr(riva,0, 18, 0x00);
NVWriteAttr(riva,0, 19, 0x00);
}

View file

@ -1,148 +0,0 @@
#ifndef BOOTVGAINITIALIZATION_H
#define BOOTVGAINITIALIZATION_H
/* Standard VGA registers */
#define VGA_ATTR_INDEX 0x3C0
#define VGA_ATTR_DATA_W 0x3C0
#define VGA_ATTR_DATA_R 0x3C1
#define VGA_IN_STAT_0 0x3C2 /* read */
#define VGA_MISC_OUT_W 0x3C2 /* write */
#define VGA_ENABLE 0x3C3
#define VGA_SEQ_INDEX 0x3C4
#define VGA_SEQ_DATA 0x3C5
#define VGA_DAC_MASK 0x3C6
#define VGA_DAC_READ_ADDR 0x3C7
#define VGA_DAC_WRITE_ADDR 0x3C8
#define VGA_DAC_DATA 0x3C9
#define VGA_FEATURE_R 0x3CA /* read */
#define VGA_MISC_OUT_R 0x3CC /* read */
#define VGA_GRAPH_INDEX 0x3CE
#define VGA_GRAPH_DATA 0x3CF
#define VGA_IOBASE_MONO 0x3B0
#define VGA_IOBASE_COLOR 0x3D0
#define VGA_CRTC_INDEX_OFFSET 0x04
#define VGA_CRTC_DATA_OFFSET 0x05
#define VGA_IN_STAT_1_OFFSET 0x0A /* read */
#define VGA_FEATURE_W_OFFSET 0x0A /* write */
/* Little macro to construct bitmask for contiguous ranges of bits */
#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1) << (b))
#define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
/* Macro to set specific bitfields (mask has to be a macro x:y) ! */
#define SetBF(mask,value) ((value) << (0?mask))
#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
#define MaskAndSetBF(var,mask,value) (var)=(((var)&(~MASKEXPAND(mask)) \
| SetBF(mask,value)))
/* SetBitField: Move bit-range in 'from' to bit-range in 'to' */
#define SetBitField(value,from,to) SetBF(to, GetBF(value,from))
#define SetBitFlag(value,mask,to) ((value & mask) ? (1 << to) : 0)
#define SetBit(n) (1<<(n))
#define GetBit(value,n) ((value)&(1<<(n)))
#define GetBitFlag(value,from,mask) (GetBit(value,from) ? mask : 0)
#define Set8Bits(value) ((value)&0xff)
#define HEAD 0x2000
#define CARD8 BYTE
#define CARD32 DWORD
#define MMIO_IN8(base, offset) \
*(volatile CARD8 *)(((CARD8*)(base)) + (offset))
#define MMIO_IN16(base, offset) \
*(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset))
#define MMIO_IN32(base, offset) \
*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
#define MMIO_OUT8(base, offset, val) \
*(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val)
#define MMIO_OUT16(base, offset, val) \
*(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
#define MMIO_OUT32(base, offset, val) \
*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
#define MMIO_ONB8(base, offset, val) MMIO_OUT8(base, offset, val)
#define MMIO_ONB16(base, offset, val) MMIO_OUT16(base, offset, val)
#define MMIO_ONB32(base, offset, val) MMIO_OUT32(base, offset, val)
#define MMIO_H_IN8(base,h,offset) MMIO_IN8(base,(offset)+(h)*HEAD)
#define MMIO_H_IN32(base,h,offset) MMIO_IN32(base,(offset)+(h)*HEAD)
#define MMIO_H_OUT8(base,h,offset,val) MMIO_OUT8(base,(offset)+(h)*HEAD,val)
#define MMIO_H_OUT32(base,h,offset,val) MMIO_OUT32(base,(offset)+(h)*HEAD,val)
#define MMIO_H_AND32(base,h,offset,val) MMIO_AND32(base,(offset)+(h)*HEAD,val)
#define MMIO_H_OR32(base,h,offset,val) MMIO_OR32(base,(offset)+(h)*HEAD,val)
#define MMIO_AND32(base, offset, val) \
*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) &= (val)
#define MMIO_OR32(base, offset, val) \
*(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) |= (val)
/* these assume memory-mapped I/O, and not normal I/O space */
#define NV_WR08(p,i,d) MMIO_OUT8((volatile void *)(p), (i), (d))
#define NV_RD08(p,i) MMIO_IN8((volatile void *)(p), (i))
#define NV_WR16(p,i,d) MMIO_OUT16((volatile void *)(p), (i), (d))
#define NV_RD16(p,i) MMIO_IN16((volatile void *)(p), (i))
#define NV_WR32(p,i,d) MMIO_OUT32((volatile void *)(p), (i), (d))
#define NV_RD32(p,i) MMIO_IN32((volatile void *)(p), (i))
#define VGA_WR08(p,i,d) NV_WR08(p,i,d)
#define VGA_RD08(p,i) NV_RD08(p,i)
#define CRT_INDEX(h) (0x3d4 + (h) * HEAD)
#define CRT_DATA(h) (0x3d5 + (h) * HEAD)
#define NV_FLAG_DOUBLE_PIX (1 << 1)
#define NV_FLAG_DOUBLE_SCAN (1 << 0)
#define DEV_TELEVISION (1 << 1)
#define DEV_FLATPANEL (1 << 2)
#define NVCRTC 0x6013D4
typedef struct _riva_hw_inst
{
/*
* Non-FIFO registers.
*/
volatile BYTE *PCRTC;
volatile BYTE *PRAMDAC;
volatile BYTE *PFB;
volatile BYTE *PFIFO;
volatile BYTE *PGRAPH;
volatile BYTE *PEXTDEV;
volatile BYTE *PTIMER;
volatile BYTE *PMC;
volatile BYTE *PRAMIN;
volatile BYTE *FIFO;
volatile BYTE *CURSOR;
volatile BYTE *CURSORPOS;
volatile BYTE *VBLANKENABLE;
volatile BYTE *VBLANK;
volatile BYTE *PCIO;
volatile BYTE *PVIO;
volatile BYTE *PDIO;
volatile BYTE *PVIDEO;
} RIVA_HW_INST;
// function prototypes, not to be called from outside BootVgaInitialization
static void mapNvMem (RIVA_HW_INST *riva, BYTE *IOAddress);
static void NVDisablePalette (RIVA_HW_INST *riva, int head);
static void NVWriteSeq(RIVA_HW_INST *riva, CARD8 index, CARD8 value);
static void NVWriteGr(RIVA_HW_INST *riva, CARD8 index, CARD8 value);
static void NVInitGrSeq (RIVA_HW_INST *riva);
static void NVInitAttr (RIVA_HW_INST *riva, int head);
static inline void unlockCrtNv (RIVA_HW_INST *riva, int head);
static inline void lockCrtNv (RIVA_HW_INST *riva, int head);
static void writeCrtNv (RIVA_HW_INST *riva, int head, int reg, BYTE val);
static void NVVertIntrEnabled (RIVA_HW_INST *riva, int head);
static void NVSetFBStart (RIVA_HW_INST *riva, int head, DWORD dwFBStart);
#endif

View file

@ -1,34 +0,0 @@
#ifndef _BootVideo_H_
#define _BootVideo_H_
enum {
VIDEO_MODE_UNKNOWN=-1,
VIDEO_MODE_640x480=0,
VIDEO_MODE_640x576,
VIDEO_MODE_720x576,
VIDEO_MODE_800x600,
VIDEO_MODE_1024x576,
VIDEO_MODE_COUNT
};
typedef struct {
// fill on entry
int m_nVideoModeIndex; // fill on entry to BootVgaInitializationKernel(), eg, VIDEO_MODE_800x600
BYTE m_fForceEncoderLumaAndChromaToZeroInitially; // fill on entry to BootVgaInitializationKernel(), 0=mode change visible immediately, !0=initially forced to black raster
DWORD m_dwFrameBufferStart; // frame buffer start address, set to zero to use default
BYTE * volatile m_pbBaseAddressVideo; // base address of video, usually 0xfd000000
// filled on exit
DWORD width; // everything else filled by BootVgaInitializationKernel() on return
DWORD height;
DWORD xmargin;
DWORD ymargin;
BYTE m_bAvPack;
DWORD m_dwVideoFadeupTimer;
double hoc;
double voc;
BYTE m_bBPP;
} CURRENT_VIDEO_MODE_DETAILS;
void BootVgaInitializationKernelNG(CURRENT_VIDEO_MODE_DETAILS * pvmode);
#endif // _BootVideo_H_

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