commit 5eb67e005ef64731fd6ec97f94768df19bdbac88 Author: Hector Martin Date: Mon Aug 8 15:33:53 2022 +0900 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..171e03d --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +git_version.h +*.d +*.bin +*.elf +*.map +*~ +*.o +.*.swp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9be399a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "mini"] + path = mini + url = https://github.com/fail0verflow/mini diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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. + + + Copyright (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. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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. + + , 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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3c006bb --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +all: bootmii.bin + +.PHONY: bootmii.bin +bootmii.bin: + @$(MAKE) -C loader + @$(MAKE) -C stub + @$(MAKE) -C resetstub + python2 mini/makebin.py stub/bootmii.bin resetstub/resetstub.elf bootmii.bin + +clean: + @$(MAKE) -C loader clean + @$(MAKE) -C stub clean + @$(MAKE) -C resetstub clean + diff --git a/README.md b/README.md new file mode 100644 index 0000000..1555139 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# BootMii loader + +This repository contains the public release of the source code for +the BootMii stub loader. + +Included portions: + +* ELF loader stub +* BootMii SD loader proper +* Reset stub +* mini (submodule) + +Not included: + +* boot2-style-wad packaging stuff +* PyWii (see hbc) +* UI/PPC side (CE1LING_CAT) +* Installer + +Note that the code in this repository may differ from the source code used to +build the official version of BootMii. + +This code is released with no warranty, and has only been build tested. +If you release this to anyone but yourself without extensive testing, you are an +irresponsible person and we will forever hate you. + +## Build instructions + +You need armeb-eabi cross compilers. Same build setup as +[mini](https://github.com/fail0verflow/mini). See +[bootmii-utils](https://github.com/fail0verflow/bootmii-utils) for some outdated +toolchain build scripts. Type `make` to compile. Good luck. + +Output is at `bootmii.bin`, which is the main `armboot.bin` style executable +for BootMii-as-IOS, with a dummy reset stub as payload. Installation as boot2 +would replace the ELF payload with the original boot2 instead. + +## Seriously + +Do NOT release this to users unless you've read +[this](https://marcan.st/2011/01/safe-hacking/) and spent months testing +hardware variations and building an installer that cross checks every step +including boot1 simulation prior to actually committing to NAND. There's a +reason we didn't brick any Wiis with this stuff. We're releasing this because +it's been over a decade and some people are asking for it to experiment with +devkits and other weird stuff, not because anyone should try using this on their +Wii. + +## License + +Unless otherwise noted in an individual file header, all source code in this +repository is released under the terms of the GNU General Public License, +version 2 or later. The full text of the license can be found in the COPYING +file. diff --git a/common.mk b/common.mk new file mode 120000 index 0000000..a3e8d5d --- /dev/null +++ b/common.mk @@ -0,0 +1 @@ +mini/common.mk \ No newline at end of file diff --git a/describe.sh b/describe.sh new file mode 100755 index 0000000..e643438 --- /dev/null +++ b/describe.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +# Check for git and a git repo. +if head=`git rev-parse --verify HEAD 2>/dev/null`; then + printf "%s" `git describe --always --match bootmii-\* \`git log --pretty=oneline -n1 | awk ' { print $1 }'\` | awk '{ sub (/bootmii-/, ""); print;}'` + + # Are there uncommitted changes? + git update-index --refresh --unmerged > /dev/null + git diff-index --quiet HEAD loader stub || printf "%s" -dirty +fi + +echo diff --git a/describesimple.sh b/describesimple.sh new file mode 100755 index 0000000..821229d --- /dev/null +++ b/describesimple.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +cd "$(dirname "$0")" + +# Check for git and a git repo. +if head=`git rev-parse --verify HEAD 2>/dev/null`; then + comm=`git log --pretty=oneline -n1 | awk ' { print $1 }'` + printf "%s" ""`printf "%s" \`git describe --always --abbrev=4 --match bootmii-\* $comm | awk '{ sub (/bootmii-/, ""); print;}'\`` + + # Are there uncommitted changes? + git update-index --refresh --unmerged > /dev/null + git diff-index --quiet HEAD loader stub || printf "%s" '*' +fi + +echo diff --git a/loader/.gitignore b/loader/.gitignore new file mode 100644 index 0000000..5e11f85 --- /dev/null +++ b/loader/.gitignore @@ -0,0 +1,7 @@ +*.d +*.bin +*.elf +*.o +*.map +loader_version.txt + diff --git a/loader/Makefile b/loader/Makefile new file mode 100644 index 0000000..4a3dd7a --- /dev/null +++ b/loader/Makefile @@ -0,0 +1,43 @@ +include ../starlet.mk + +TARGET = bootmii-sym.elf +TARGET_STRIPPED = bootmii.elf + +OBJS = start.o main.o vsprintf.o string.o gecko.o memory.o memory_asm.o \ + sdhc.o sdmmc.o utils.o ff.o diskio.o lcd.o version.o + +CFLAGS = -mbig-endian -mthumb -march=armv5t +CFLAGS += -fomit-frame-pointer -ffunction-sections +CFLAGS += -Wall -Wextra -Os -pipe + +# uncomment to enabled LCD debug output +#DEFINES += -DENABLE_LCD +DEFINES += -DLOADER + +LDFLAGS += -Wl,-N +LDSCRIPT = loader.ld +LIBS = -lgcc + +include ../common.mk + +all: $(TARGET_STRIPPED) loader_version.txt + +$(TARGET_STRIPPED): $(TARGET) + @echo " STRIP $@" + @cp $< $@ + @$(STRIP) -R .comment -R .ARM.attributes -s $@ + +version.o: version.c ../describe.sh + @echo " VERSION $@" + @cat $< | sed "s/%VERSION%/`../describe.sh`/" | $(CC) $(CFLAGS) -c -x c - -o $@ + +loader_version.txt: ../describe.sh + @../describe.sh > loader_version.txt + +clean: myclean + +myclean: + -rm -f $(TARGET_STRIPPED) loader_version.txt + +.PHONY: version.o + diff --git a/loader/bsdtypes.h b/loader/bsdtypes.h new file mode 120000 index 0000000..42841c5 --- /dev/null +++ b/loader/bsdtypes.h @@ -0,0 +1 @@ +../mini/bsdtypes.h \ No newline at end of file diff --git a/loader/diskio.c b/loader/diskio.c new file mode 120000 index 0000000..784113e --- /dev/null +++ b/loader/diskio.c @@ -0,0 +1 @@ +../mini/diskio.c \ No newline at end of file diff --git a/loader/diskio.h b/loader/diskio.h new file mode 120000 index 0000000..4c69508 --- /dev/null +++ b/loader/diskio.h @@ -0,0 +1 @@ +../mini/diskio.h \ No newline at end of file diff --git a/loader/elf.h b/loader/elf.h new file mode 120000 index 0000000..430152d --- /dev/null +++ b/loader/elf.h @@ -0,0 +1 @@ +../mini/elf.h \ No newline at end of file diff --git a/loader/errno.h b/loader/errno.h new file mode 120000 index 0000000..ab85a4f --- /dev/null +++ b/loader/errno.h @@ -0,0 +1 @@ +../mini/errno.h \ No newline at end of file diff --git a/loader/ff.c b/loader/ff.c new file mode 120000 index 0000000..ecab8ff --- /dev/null +++ b/loader/ff.c @@ -0,0 +1 @@ +../mini/ff.c \ No newline at end of file diff --git a/loader/ff.h b/loader/ff.h new file mode 120000 index 0000000..0f2ca3b --- /dev/null +++ b/loader/ff.h @@ -0,0 +1 @@ +../mini/ff.h \ No newline at end of file diff --git a/loader/gecko.c b/loader/gecko.c new file mode 100644 index 0000000..74e725b --- /dev/null +++ b/loader/gecko.c @@ -0,0 +1,173 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + USBGecko support code + +Copyright (c) 2008 Nuke - +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2009 Andre Heider "dhewg" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "types.h" +#include "start.h" +#include "vsprintf.h" +#include "string.h" +#include "utils.h" +#include "hollywood.h" +#include "gecko.h" + +static int gecko_active = 0; + +static u32 _gecko_command(u32 command) +{ + u32 i; + // Memory Card Port B (Channel 1, Device 0, Frequency 3 (32Mhz Clock)) + write32(EXI1_CSR, 0xd0); + write32(EXI1_DATA, command); + write32(EXI1_CR, 0x19); + while (read32(EXI1_CR) & 1); + i = read32(EXI1_DATA); + write32(EXI1_CSR, 0); + return i; +} + +static u32 _gecko_getid(void) +{ + u32 i; + // Memory Card Port B (Channel 1, Device 0, Frequency 3 (32Mhz Clock)) + write32(EXI1_CSR, 0xd0); + write32(EXI1_DATA, 0); + write32(EXI1_CR, 0x19); + while (read32(EXI1_CR) & 1); + write32(EXI1_CR, 0x39); + while (read32(EXI1_CR) & 1); + i = read32(EXI1_DATA); + write32(EXI1_CSR, 0); + return i; +} + +static u32 _gecko_sendbyte(char sendbyte) +{ + u32 i = 0; + i = _gecko_command(0xB0000000 | (sendbyte<<20)); + if (i&0x04000000) + return 1; // Return 1 if byte was sent + return 0; +} + +static u32 _gecko_checksend(void) +{ + u32 i = 0; + i = _gecko_command(0xC0000000); + if (i&0x04000000) + return 1; // Return 1 if safe to send + return 0; +} + +int gecko_isalive(void) +{ + u32 i; + u32 id; + id = _gecko_getid(); + if(id != 0x00000000) + return 0; + i = _gecko_command(0x90000000); + if ((i&0xFFFF0000) != 0x04700000) + return 0; + return 1; +} + +void gecko_init(void) +{ + write32(EXI0_CSR, 0); + write32(EXI1_CSR, 0); + write32(EXI2_CSR, 0); + write32(EXI0_CSR, 0x2000); + write32(EXI0_CSR, 3<<10); + write32(EXI1_CSR, 3<<10); + + gecko_active = 0; + if(gecko_isalive()) + gecko_active = 1; +} + +#if 0 +int gecko_sendbuffer(const void *buffer, u32 size) +{ + u32 left = size; + char *ptr = (char*)buffer; + + while(left>0) { + if(!_gecko_sendbyte(*ptr)) + break; + ptr++; + left--; + } + return (size - left); +} +#endif + +int gecko_sendbuffer_safe(const void *buffer, u32 size) +{ + u32 left = size; + char *ptr = (char*)buffer; + + int tries = 10000; // about 200ms of tries + + if((read32(HW_EXICTRL) & EXICTRL_ENABLE_EXI) == 0) + return left; + + while(left>0) { + if(_gecko_checksend()) { + if(!_gecko_sendbyte(*ptr)) + break; + ptr++; + left--; + } else { + // if gecko is hung, time out and disable further attempts + // only affects gecko users without an active terminal + if(tries-- == 0) { + gecko_active = 0; + break; + } + } + } + return (size - left); +} + +#if 0 +int gecko_putchar(int ic) +{ + char b = ic; + + if(!gecko_active) + return -1; + return gecko_sendbuffer(&b, 1); +} +#endif + +int gecko_puts(const char *s) +{ + if(!gecko_active) + return -1; + return gecko_sendbuffer_safe(s, strlen(s)); +} + +int gecko_printf( const char *fmt, ...) +{ + va_list args; + char buffer[256]; + int i; + + if(!gecko_active) + return -1; + + va_start(args, fmt); + i = vsprintf(buffer, fmt, args); + va_end(args); + gecko_puts(buffer); + return i; +} diff --git a/loader/gecko.h b/loader/gecko.h new file mode 100644 index 0000000..969cd4c --- /dev/null +++ b/loader/gecko.h @@ -0,0 +1,31 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + USBGecko support code + +Copyright (c) 2008 Nuke - +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2009 Andre Heider "dhewg" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __GECKO_H__ +#define __GECKO_H__ + +#include "types.h" + +void gecko_flush(void); +int gecko_isalive(void); +int gecko_recvbuffer(void *buffer, u32 size); +int gecko_sendbuffer(const void *buffer, u32 size); +int gecko_recvbuffer_safe(void *buffer, u32 size); +int gecko_sendbuffer_safe(const void *buffer, u32 size); +int gecko_putchar(int c); +int gecko_getchar(void); +int gecko_puts(const char *s); +int gecko_printf( const char *fmt, ...); +void gecko_init(void); + +#endif diff --git a/loader/gpio.h b/loader/gpio.h new file mode 120000 index 0000000..9687b89 --- /dev/null +++ b/loader/gpio.h @@ -0,0 +1 @@ +../mini/gpio.h \ No newline at end of file diff --git a/loader/hollywood.h b/loader/hollywood.h new file mode 120000 index 0000000..19e5223 --- /dev/null +++ b/loader/hollywood.h @@ -0,0 +1 @@ +../mini/hollywood.h \ No newline at end of file diff --git a/loader/integer.h b/loader/integer.h new file mode 120000 index 0000000..02c2853 --- /dev/null +++ b/loader/integer.h @@ -0,0 +1 @@ +../mini/integer.h \ No newline at end of file diff --git a/loader/irq.h b/loader/irq.h new file mode 120000 index 0000000..48957e4 --- /dev/null +++ b/loader/irq.h @@ -0,0 +1 @@ +../mini/irq.h \ No newline at end of file diff --git a/loader/lcd.c b/loader/lcd.c new file mode 100644 index 0000000..0ec4a33 --- /dev/null +++ b/loader/lcd.c @@ -0,0 +1,225 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + GPIO LCD display support + + (yes, that thing in that youtube video) + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifdef ENABLE_LCD + +#include "types.h" +#include "lcd.h" +#include "start.h" +#include "vsprintf.h" +#include "string.h" +#include "utils.h" +#include "hollywood.h" + +void lcdinit(void); + +char ddram[0x80]; +u8 ddaddr = 0; +u32 chardelay = 0; + +#define WIDTH 16 +#define HEIGHT 2 + +u8 linestarts[HEIGHT] = { 0x00, 0x40 }; + +u8 cx, cy; + +// for 4x20 +//u8 linestarts[HEIGHT] = { 0x00, 0x40, 0x14, 0x54 }; + +#define LCD_HOME_CLEAR 0x01 +#define LCD_HOME 0x02 +#define LCD_ENTRY_MODE 0x04 +# define EM_INC 0x02 +# define EM_DEC 0x00 +# define EM_SHIFT 0x01 +#define LCD_DISPLAY_ONOFF 0x08 +# define D_DISPLAY 0x04 +# define D_CURSOR 0x02 +# define D_BLINK 0x01 +#define LCD_SHIFT 0x10 +# define SH_SHIFT 0x08 +# define SH_CURSOR 0x00 +# define SH_RIGHT 0x04 +# define SH_LEFT 0x00 +#define LCD_FUNCTION_SET 0x20 +# define FS_8BIT 0x10 +# define FS_4BIT 0x00 +# define FS_2LINE 0x08 +# define FS_1LINE 0x00 +# define FS_5X10 0x04 +# define FS_5X8 0x00 +#define LCD_CGRAM 0x40 +#define LCD_DDRAM 0x80 + +#define LCD_PORT HW_GPIO1OUT +#define LCD_MASK 0x00FC0000 +#define LCD_E 0x00040000 +#define LCD_RS 0x00080000 +#define LCD_DSHIFT 20 + +static void _lcdnybble(char rs, char n) +{ + if(rs) + mask32(LCD_PORT, LCD_MASK, ((n&0xF) << LCD_DSHIFT) | LCD_RS); + else + mask32(LCD_PORT, LCD_MASK, ((n&0xF) << LCD_DSHIFT)); + + udelay(4); + set32(HW_GPIO1OUT, LCD_E); + udelay(4); + clear32(HW_GPIO1OUT, LCD_E); + udelay(4); +} + +static void _lcdcmd(char c) +{ + _lcdnybble(0, c>>4); + _lcdnybble(0, c&0x0F); + udelay(50); +} + +static void _lcdwrite(char c) +{ + _lcdnybble(1, c>>4); + _lcdnybble(1, c&0x0F); + ddram[ddaddr] = c; + ddaddr = (ddaddr+1)&0x7F; + udelay(50); +} + +static void _lcdgoto(u8 addr) +{ + _lcdcmd(LCD_DDRAM | addr); + ddaddr = addr; +} + +static void _lcdgotoxy(u8 x, u8 y) +{ + u8 addr = (x + linestarts[y]); + _lcdcmd(LCD_DDRAM | addr); + ddaddr = addr; +} + +static void _lcdclear(void) +{ + int i; + _lcdcmd(LCD_HOME_CLEAR); + udelay(2000); + for(i=0;i<0x80;i++) { + ddram[i] = ' '; + } +} + +static void _lcdscroll(u8 count) +{ + int x,y; + _lcdcmd(LCD_HOME_CLEAR); + udelay(2000); + for(y=0;y<(HEIGHT-count);y++) { + _lcdgotoxy(0,y); + for(x=0;x>4); + udelay(10000); + _lcdnybble(0, (LCD_FUNCTION_SET | FS_8BIT)>>4); + udelay(1000); + _lcdnybble(0, (LCD_FUNCTION_SET | FS_8BIT)>>4); + udelay(1000); + _lcdnybble(0, (LCD_FUNCTION_SET | FS_4BIT)>>4); + udelay(1000); + _lcdcmd(LCD_FUNCTION_SET | FS_4BIT | FS_2LINE | FS_5X8); + _lcdcmd(LCD_DISPLAY_ONOFF); + _lcdcmd(LCD_HOME_CLEAR); + udelay(2000); + _lcdcmd(LCD_ENTRY_MODE | EM_INC); + _lcdcmd(LCD_DISPLAY_ONOFF | D_DISPLAY | D_CURSOR); +} + +int lcd_putchar(int ic) +{ + char c = ic; + // defer newlines to keep last line of LCD full + if(c == '\n') { + cx = 0; + cy++; + if(cy < HEIGHT) + _lcdgotoxy(cx,cy); + } else { + if(cx >= 16) { + cx = 0; + cy++; + if(cy < HEIGHT) + _lcdgotoxy(cx,cy); + } + if(cy >= (2*HEIGHT-1)) { + _lcdclear(); + _lcdgoto(linestarts[HEIGHT-1]); + cy = HEIGHT - 1; + cx = 0; + } else if(cy >= HEIGHT) { + _lcdscroll(cy - HEIGHT + 1); + cy = HEIGHT - 1; + cx = 0; + } + _lcdwrite(c); + cx++; + } + return (u8)c; +} + +void lcd_setdelay(u32 delay) +{ + chardelay = delay; +} + +int lcd_puts(const char *s) +{ + while(*s) { + lcd_putchar(*s++); + udelay(chardelay); + } + return 0; +} + +int lcd_printf( const char *fmt, ...) +{ + va_list args; + char buffer[1024]; + int i; + + va_start(args, fmt); + i = vsprintf(buffer, fmt, args); + va_end(args); + lcd_puts(buffer); + return i; +} + +#endif + diff --git a/loader/lcd.h b/loader/lcd.h new file mode 100644 index 0000000..929ef07 --- /dev/null +++ b/loader/lcd.h @@ -0,0 +1,37 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + GPIO LCD display support + + (yes, that thing in that youtube video) + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __LCD_H__ +#define __LCD_H__ + +#ifdef ENABLE_LCD + +#include "types.h" + +void lcd_init(void); +int lcd_putchar(int c); +int lcd_puts(const char *s); +void lcd_setdelay(u32 delay); +int lcd_printf( const char *fmt, ...); + +#else + +#define lcd_init(...) +#define lcd_putchar(...) +#define lcd_puts(...) +#define lcd_setdelay(...) +#define lcd_printf(...) + +#endif + +#endif + diff --git a/loader/loader.ld b/loader/loader.ld new file mode 100644 index 0000000..a3eb796 --- /dev/null +++ b/loader/loader.ld @@ -0,0 +1,90 @@ +/* + mini - a Free Software replacement for the Nintendo/BroadOn IOS. + linker script + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +OUTPUT_FORMAT("elf32-bigarm") +OUTPUT_ARCH(arm) +EXTERN(_start) +ENTRY(_start) + +__base_addr = 0x10400000; + +PHDRS +{ + init PT_LOAD FLAGS(5); + text PT_LOAD FLAGS(5); + data PT_LOAD FLAGS(6); + bss PT_LOAD FLAGS(6); +} + +SECTIONS +{ + . = __base_addr; + + .init : + { + *(.init) + *(.init.*) + . = ALIGN(4); + } :init + + .text : + { + *(.text) + *(.text.*) + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + } :text + + __text_end = . ; + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + . = ALIGN(4); + } :data + + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + } :data + + .bss : + { + __bss_start = . ; + *(.dynbss) + *(.gnu.linkonce.b*) + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(4); + __bss_end = . ; + } :bss + + . = ALIGN(4); + __stack_end = .; + __stack_addr = (__stack_end + 0x4000); + __end = __stack_addr ; +} + +PROVIDE (__stack_end = __stack_end); +PROVIDE (__stack_addr = __stack_addr); +PROVIDE (__bss_start = __bss_start); +PROVIDE (__bss_end = __bss_end); +PROVIDE (__end = __end); diff --git a/loader/main.c b/loader/main.c new file mode 100644 index 0000000..af9e8e4 --- /dev/null +++ b/loader/main.c @@ -0,0 +1,390 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + Main loader code + +Copyright (C) 2008, 2009 Haxx Enterprises +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2009 Andre Heider "dhewg" +Copyright (C) 2009 John Kelley + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "types.h" +#include "utils.h" +#include "start.h" +#include "hollywood.h" +#include "sdhc.h" +#include "string.h" +#include "memory.h" +#include "elf.h" +#include "gecko.h" +#include "ff.h" +#include "lcd.h" +#include "gpio.h" + +#define BOOT_FILE "/bootmii/armboot.bin" + +extern void *__end; +extern const char *bootmii_version; + +static FATFS fatfs; + +static void hexline(void *addr, int len) +{ + u8 *p = (u8*)addr; + while(len--) { + gecko_printf("%02x",*p++); + } +} + +static void printhdr(ioshdr *hdr) { + gecko_printf("ARMBOOT header (@%p):\n",hdr); + gecko_printf(" Header size: %08x\n", hdr->hdrsize); + gecko_printf(" Loader size: %08x\n", hdr->loadersize); + gecko_printf(" ELF size: %08x\n", hdr->elfsize); + gecko_printf(" Argument: %08x\n", hdr->argument); + gecko_printf(" ELF at %p\n", (u8 *) hdr + hdr->hdrsize + hdr->loadersize); +} + +static void loadelf(u8 *elf) { + gecko_puts("Loading ELF...\n"); + + if(memcmp("\x7F" "ELF\x01\x02\x01\x61\x01",elf,9)) { + gecko_printf("Invalid ELF header:\n"); + hexline(elf, 9); + gecko_printf("\n"); + panic(0xE3); + } + + Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf; + if(ehdr->e_phoff == 0) { + gecko_printf("ELF has no program headers!\n"); + panic(0xE4); + } + + int count = ehdr->e_phnum; + Elf32_Phdr *phdr = (Elf32_Phdr*)(elf + ehdr->e_phoff); + gecko_printf("PHDRS at %p\n",phdr); + while(count--) + { + if(phdr->p_type != PT_LOAD) { + gecko_printf(" Skipping PHDR of type %d\n",phdr->p_type); + } else { + void *src = elf + phdr->p_offset; + gecko_printf(" LOAD %p -> %x [0x%x]\n",src, phdr->p_paddr, phdr->p_filesz); + memcpy((void *)phdr->p_paddr, src, phdr->p_filesz); + } + phdr++; + } +} + +static void turn_stuff_on(void) +{ + clear32(HW_GPIO1OUT, 0x10); + udelay(100); + set32(HW_RESETS, 0x7ffffcf); +} + +static void reset_audio(void) +{ + mask32(HW_DIFLAGS, 0x180, 0x100); + + clear32(0xd8001d0, 0x80000000); + udelay(2); + clear32(0xd8001d0, 0x40000000); + + clear32(0xd8001d0, 0x10000000); + mask32(0xd8001cc, 0x7ffffff, 0x4b0ffce); + + udelay(10); + set32(0xd8001d0, 0x40000000); + udelay(500); + set32(0xd8001d0, 0x80000000); + udelay(2); +} + +static void boot2_init1() +{ + //func_ffff5d08 + u32 reg = read32(0xd8001c8); + + if((reg & 0xc0000000) == 0xc0000000) + return; + + clear32(0xd8001c8, 0x80000000); + udelay(2); + clear32(0xd8001c8, 0x40000000); + udelay(10); + set32(0xd8001c8, 0x40000000); + udelay(50); + set32(0xd8001c8, 0x80000000); + udelay(2); +} + +static void boot2_init2(u32 hlywdVerHi) +{ + //func_ffff5c40 + + write32(0xd800088, 0xFE); + udelay(2); + + clear32(0xd8001d8, 0x80000000); + udelay(2); + clear32(0xd8001d8, 0x40000000); + udelay(10); + set32(0xd8001d8, 0x40000000); + udelay(50); + set32(0xd8001d8, 0x80000000); + udelay(2); + + write32(0xd800088, 0xF6); + udelay(50); + write32(0xd800088, 0xF4); + udelay(1); + write32(0xd800088, 0xF0); + udelay(1); + write32(0xd800088, 0x70); + udelay(1); + write32(0xd800088, 0x60); + udelay(1); + write32(0xd800088, 0x40); + udelay(1); + write32(0xd800088, 0); + udelay(1); + write32(0xd0400b4, 0x2214); + if (hlywdVerHi) + write32(0xd0400b0, 0x20600); + else + write32(0xd0400b0, 0x20400); + write32(0xd0400a4, 0x26); + udelay(1); + write32(0xd0400a4, 0x2026); + udelay(1); + write32(0xd0400a4, 0x4026); + udelay(20); + write32(0xd0400cc, 0x111); +} + +static void setup_gpios() +{ + write32(HW_GPIO1OWNER, GP_OWNER_PPC); + mask32(HW_GPIO1OUT, GP_ARM_OUTPUTS, GP_ARM_DEFAULT_ON); + write32(HW_GPIO1DIR, GP_ARM_OUTPUTS); + mask32(HW_GPIO1BOUT, GP_PPC_OUTPUTS, GP_PPC_DEFAULT_ON); + write32(HW_GPIO1BDIR, GP_PPC_OUTPUTS); + write32(HW_GPIO1ENABLE, GP_ALL); + udelay(2000); + write32(HW_GPIO1INTLVL, 0); + write32(HW_GPIO1INTFLAG, GP_ALL); + write32(HW_GPIO1INTENABLE, 0); + write32(HW_GPIO1BINTLVL, 0); + write32(HW_GPIO1BINTFLAG, GP_ALL); + write32(HW_GPIO1BINTENABLE, 0); +} + +static void hardware_setup(void) +{ + u8 hwood_ver, hwood_hi, hwood_lo; + hwood_ver = read32(HW_VERSION) & 0xFF; + hwood_hi = hwood_ver >> 4; + hwood_lo = hwood_ver & 0xF; + + debug_output(0x03); + + set32(HW_EXICTRL, EXICTRL_ENABLE_EXI); + + mem_protect(1, (void*)0x13420000, (void*)0x1fffffff); + + clear32(HW_EXICTRL, 0x10); + if(hwood_hi == 0) + write32(0xd8b0010, 0); + write32(0xd8b0010, 0); + if(hwood_hi == 1 && hwood_lo == 0) + mask32(0xd800140, 0x0000FFF0, 1); + + set32(0xd80018c, 0x400); + set32(0xd80018c, 0x800); + + reset_audio(); + boot2_init1(); + boot2_init2(hwood_hi); + setup_gpios(); + turn_stuff_on(); + + write32(0xd8001e0, 0x65244A); + write32(0xd8001e4, 0x46A024); + + debug_output(0x73); + + clear32(HW_GPIO1OWNER, 0x10); + set32(HW_GPIO1DIR, 0x10); +} + +void *_main(void *base) +{ + FRESULT fres; + + ioshdr *hdr = (ioshdr*)base; + ioshdr *filehdr; + u8 *elf; + + u32 bypass = 0; + + elf = (u8*) base; + elf += hdr->hdrsize + hdr->loadersize; + + debug_output(0xF0); + lcd_init(); + hardware_setup(); + debug_output(0xF1); + + if (read32(0x150effc) == 0x53544655) + write32(0x150effc, 0); + else + gecko_init(); + + lcd_puts("BootMii\n"); + lcd_puts("\n"); + + gecko_puts("\n\nBootMii v"); + gecko_puts(bootmii_version); + gecko_puts("\n"); + + gecko_puts("Copyright (C) 2008-2010 Team Twiizers.\n"); + gecko_puts("Licensed under the GNU GPL version 2.\n"); + + printhdr(hdr); + + if(hdr->argument == 0x42) { + bypass = 1; + goto boot2; + } + + if (read32(0x150f000) == 0x424d454d) { + gecko_puts("Trying to boot ELF from memory\n"); + + filehdr = (ioshdr *) read32(0x150f004); + write32(0x150f000, 0); + write32(0x150f004, 0); + + printhdr(filehdr); + void *entry = (void*)(((u32)filehdr) + filehdr->hdrsize); + + lcd_puts(" ~ ARMBOOT \n"); + gecko_printf("Launching ARMBOOT @ %p\n\n",entry); + + debug_output(0xF3); + + return entry; + } + + gecko_puts("Trying to mount SD...\n"); + + sdhc_init(); + fres = f_mount(0, &fatfs); + + if(fres != FR_OK) { + gecko_printf("Error %d while trying to mount SD\n", fres); + debug_output(0x12); + debug_output(fres&0xFF); + goto boot2; + } + + //debug_output(0xF2); + + gecko_puts("Trying to open SD:" BOOT_FILE "\n"); + + FIL fd; + u32 read; + + fres = f_open(&fd, BOOT_FILE, FA_READ); + if(fres != FR_OK) { + gecko_printf("Error %d while trying to open file\n", fres); + //debug_output(0x13); + //debug_output(fres&0xFF); + goto boot2; + } + + lcd_puts("."); + debug_output(0xF2); + + filehdr = (ioshdr *)ALIGN_FORWARD(((u32)&__end) + 0x100, 0x100); + + gecko_printf("Trying to read ARMBOOT header to %p\n", filehdr); + + fres = f_read(&fd, filehdr, sizeof(ioshdr), &read); + if(fres != FR_OK) { + gecko_printf("Error %d while trying to read file header\n", fres); + //debug_output(0x14); + //debug_output(fres&0xFF); + goto boot2; + } + if(read != sizeof(ioshdr)) { + gecko_printf("Got %d bytes, expected %d\n", read, sizeof(ioshdr)); + //debug_output(0x24); + goto boot2; + } + + lcd_puts("."); + //debug_output(0xF5); + + printhdr(filehdr); + + u32 totalsize = filehdr->hdrsize + filehdr->loadersize + filehdr->elfsize; + + gecko_printf("Total ARMBOOT size: 0x%x\n", totalsize); + gecko_printf("Trying to read ARMBOOT to %p\n", filehdr); + + fres = f_read(&fd, filehdr+1, totalsize-sizeof(ioshdr), &read); + if(fres != FR_OK) { + gecko_printf("Error %d while trying to read file header\n", fres); + //debug_output(0x15); + //debug_output(fres&0xFF); + goto boot2; + } + if(read != (totalsize-sizeof(ioshdr))) { + gecko_printf("Got %d bytes, expected %d\n", read, (totalsize-sizeof(ioshdr))); + //debug_output(0x25); + goto boot2; + } + + lcd_puts("."); + + //debug_output(0xF6); + + gecko_puts("ARMBOOT read\n"); + + void *entry = (void*)(((u32)filehdr) + filehdr->hdrsize); + + lcd_puts(" ~ ARMBOOT \n"); + + gecko_printf("Launching ARMBOOT @ %p\n\n",entry); + + debug_output(0xF3); + + return entry; + +boot2: + debug_output(0xC8); + if(bypass) { + gecko_puts("In bypass mode, loading boot2\n"); + } else { + gecko_puts("Couldn't load from SD, falling back to boot2\n"); + set32(HW_GPIO1BOUT, GP_SLOTLED); + udelay(30000); + clear32(HW_GPIO1BOUT, GP_SLOTLED); + udelay(50000); + set32(HW_GPIO1BOUT, GP_SLOTLED); + udelay(30000); + clear32(HW_GPIO1BOUT, GP_SLOTLED); + udelay(50000); + } + lcd_puts(" ~ BOOT2 \n"); + loadelf(elf); + debug_output(0xC9); + gecko_puts("Starting boot2...\n\n"); + return (void *) 0xFFFF0000; +} diff --git a/loader/memory.c b/loader/memory.c new file mode 120000 index 0000000..2129fe8 --- /dev/null +++ b/loader/memory.c @@ -0,0 +1 @@ +../mini/memory.c \ No newline at end of file diff --git a/loader/memory.h b/loader/memory.h new file mode 120000 index 0000000..328e48e --- /dev/null +++ b/loader/memory.h @@ -0,0 +1 @@ +../mini/memory.h \ No newline at end of file diff --git a/loader/memory_asm.S b/loader/memory_asm.S new file mode 120000 index 0000000..f4811a9 --- /dev/null +++ b/loader/memory_asm.S @@ -0,0 +1 @@ +../mini/memory_asm.S \ No newline at end of file diff --git a/loader/sdhc.c b/loader/sdhc.c new file mode 120000 index 0000000..8ae61e6 --- /dev/null +++ b/loader/sdhc.c @@ -0,0 +1 @@ +../mini/sdhc.c \ No newline at end of file diff --git a/loader/sdhc.h b/loader/sdhc.h new file mode 120000 index 0000000..2a4eaeb --- /dev/null +++ b/loader/sdhc.h @@ -0,0 +1 @@ +../mini/sdhc.h \ No newline at end of file diff --git a/loader/sdmmc.c b/loader/sdmmc.c new file mode 120000 index 0000000..ac5cf6b --- /dev/null +++ b/loader/sdmmc.c @@ -0,0 +1 @@ +../mini/sdmmc.c \ No newline at end of file diff --git a/loader/sdmmc.h b/loader/sdmmc.h new file mode 120000 index 0000000..695881b --- /dev/null +++ b/loader/sdmmc.h @@ -0,0 +1 @@ +../mini/sdmmc.h \ No newline at end of file diff --git a/loader/start.S b/loader/start.S new file mode 100644 index 0000000..e9d0bdc --- /dev/null +++ b/loader/start.S @@ -0,0 +1,78 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + system startup + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +.arm + +.extern _main +.extern __got_start +.extern __got_end +.extern __bss_start +.extern __bss_end +.extern __stack_addr +.globl _start +.globl debug_output + +.section .init + +_start: + @ Get loader base from parent + mov r4, r0 + + @ Output 0x42 to the debug port + mov r0, #0x42 + bl debug_output + + @ Set up a stack + ldr sp, =__stack_addr + + @ Output 0x43 to the debug port + mov r0, #0x43 + bl debug_output + + @ clear BSS + ldr r1, =__bss_start + ldr r2, =__bss_end + mov r3, #0 +bss_loop: + @ check for the end + cmp r1, r2 + bge done_bss + @ clear the word and move on + str r3, [r1] + add r1, r1, #4 + b bss_loop + +done_bss: + mov r0, #0x44 + bl debug_output + @ take the plunge + mov r0, r4 + ldr r1, =_main+1 + mov lr, pc + bx r1 + @ _main returned! Go to whatever address it returned... + mov pc, r0 + +.pool + +debug_output: + @ load address of port + mov r3, #0xd800000 + @ load old value + ldr r2, [r3, #0xe0] + @ clear debug byte + bic r2, r2, #0xFF0000 + @ insert new value + and r0, r0, #0xFF + orr r2, r2, r0, LSL #16 + @ store back + str r2, [r3, #0xe0] + bx lr + diff --git a/loader/start.h b/loader/start.h new file mode 120000 index 0000000..9abaeac --- /dev/null +++ b/loader/start.h @@ -0,0 +1 @@ +../mini/start.h \ No newline at end of file diff --git a/loader/string.c b/loader/string.c new file mode 120000 index 0000000..92bbfe5 --- /dev/null +++ b/loader/string.c @@ -0,0 +1 @@ +../mini/string.c \ No newline at end of file diff --git a/loader/string.h b/loader/string.h new file mode 120000 index 0000000..48c55a6 --- /dev/null +++ b/loader/string.h @@ -0,0 +1 @@ +../mini/string.h \ No newline at end of file diff --git a/loader/types.h b/loader/types.h new file mode 120000 index 0000000..777aee0 --- /dev/null +++ b/loader/types.h @@ -0,0 +1 @@ +../mini/types.h \ No newline at end of file diff --git a/loader/utils.c b/loader/utils.c new file mode 120000 index 0000000..13e7651 --- /dev/null +++ b/loader/utils.c @@ -0,0 +1 @@ +../mini/utils.c \ No newline at end of file diff --git a/loader/utils.h b/loader/utils.h new file mode 120000 index 0000000..e7cc5a7 --- /dev/null +++ b/loader/utils.h @@ -0,0 +1 @@ +../mini/utils.h \ No newline at end of file diff --git a/loader/version.c b/loader/version.c new file mode 100644 index 0000000..19fd8ba --- /dev/null +++ b/loader/version.c @@ -0,0 +1 @@ +const char *bootmii_version = "%VERSION%"; diff --git a/loader/vsprintf.c b/loader/vsprintf.c new file mode 120000 index 0000000..f398df8 --- /dev/null +++ b/loader/vsprintf.c @@ -0,0 +1 @@ +../mini/vsprintf.c \ No newline at end of file diff --git a/loader/vsprintf.h b/loader/vsprintf.h new file mode 120000 index 0000000..bd61433 --- /dev/null +++ b/loader/vsprintf.h @@ -0,0 +1 @@ +../mini/vsprintf.h \ No newline at end of file diff --git a/mini b/mini new file mode 160000 index 0000000..befb64c --- /dev/null +++ b/mini @@ -0,0 +1 @@ +Subproject commit befb64ce1cd493946c9a9a0a412262a998f478d9 diff --git a/resetstub/.gitignore b/resetstub/.gitignore new file mode 100644 index 0000000..5099253 --- /dev/null +++ b/resetstub/.gitignore @@ -0,0 +1 @@ +*.elf diff --git a/resetstub/Makefile b/resetstub/Makefile new file mode 100644 index 0000000..2a23f0d --- /dev/null +++ b/resetstub/Makefile @@ -0,0 +1,23 @@ +include ../starlet.mk + +CFLAGS += -fpic +LDSCRIPT = stub.ld +LIBS = + +TARGET = resetstub-sym.elf +TARGET_STRIPPED = resetstub.elf +OBJS = stub.o + +include ../common.mk + +all: $(TARGET_STRIPPED) + +$(TARGET_STRIPPED): $(TARGET) + @echo "STRIP $@" + @$(STRIP) $< -o $@ + +clean: myclean + +myclean: + -rm -f $(TARGET) $(TARGET_STRIPPED) + diff --git a/resetstub/stub.S b/resetstub/stub.S new file mode 100644 index 0000000..6605043 --- /dev/null +++ b/resetstub/stub.S @@ -0,0 +1,31 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + dummy reset stub + +Copyright (C) 2008, 2009 Sven Peter + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +.global _start + +.arm +_start: + # enable boot0 memory mapping + ldr r0, =0x0d80018c + ldr r1, =0x1000 + ldr r2, [r0] + bic r2, r1 + str r2, [r0] + + # setup boot0 memory mirror to x'ffff_0000 + ldr r0, =0x0d800060 + mov r2, #0x20 + ldr r1, [r0] + bic r1, r2 + str r1, [r0] + + # jump to boot0 + ldr r0, =0xffff0000 + bx r0 diff --git a/resetstub/stub.ld b/resetstub/stub.ld new file mode 100644 index 0000000..094b4dc --- /dev/null +++ b/resetstub/stub.ld @@ -0,0 +1,78 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + reset stub linker script + +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2009 Andre Heider "dhewg" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +OUTPUT_FORMAT("elf32-bigarm") +OUTPUT_ARCH(arm) +EXTERN(_start) +EXTERN(__ipc_info) +ENTRY(_start) + +MEMORY { + ram : ORIGIN = 0x93ff0000, LENGTH = 64K +} + +SECTIONS +{ + .init : + { + *(.init) + . = ALIGN(4); + } >ram + + .text : + { + *(.text*) + *(.text.*) + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + } >ram + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + . = ALIGN(4); + } >ram + + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + } >ram + + .bss : + { + __bss_start = . ; + *(.dynbss) + *(.gnu.linkonce.b*) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end = . ; + } >ram + + /DISCARD/ : + { + *(.ARM.exidx*) + *(.ARM.extab*) + } + +} + + diff --git a/starlet.mk b/starlet.mk new file mode 120000 index 0000000..41e9eba --- /dev/null +++ b/starlet.mk @@ -0,0 +1 @@ +mini/starlet.mk \ No newline at end of file diff --git a/stub/.gitignore b/stub/.gitignore new file mode 100644 index 0000000..bfbdbf1 --- /dev/null +++ b/stub/.gitignore @@ -0,0 +1,6 @@ +*.d +*.bin +*.elf +*.o +*.map + diff --git a/stub/Makefile b/stub/Makefile new file mode 100644 index 0000000..5d86bca --- /dev/null +++ b/stub/Makefile @@ -0,0 +1,27 @@ +include ../starlet.mk + +CFLAGS += -fpic +LDSCRIPT = stub.ld +LIBS = -lgcc + +TARGET = bootmii.elf +TARGET_BIN = bootmii.bin +OBJS = start.o stub.o loader.o utils.o + +include ../common.mk + +all: $(TARGET_BIN) + +$(TARGET_BIN): $(TARGET) + @echo " OBJCPY $@" + @$(OBJCOPY) -O binary $< $@ + +loader.o : ../loader/bootmii.elf + @echo " BIN2O $@" + @$(BIN2S) -a 32 $< | $(AS) -o $(@) + +clean: myclean + +myclean: + -rm -f $(TARGET_BIN) + diff --git a/stub/elf.h b/stub/elf.h new file mode 100644 index 0000000..4eac370 --- /dev/null +++ b/stub/elf.h @@ -0,0 +1,54 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + ELF structures + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __ELF_H__ +#define __ELF_H__ + +#include "types.h" + +#define EI_NIDENT 16 + +typedef struct { + unsigned char e_ident[EI_NIDENT]; + u16 e_type; + u16 e_machine; + u32 e_version; + void *e_entry; + u32 e_phoff; + u32 e_shoff; + u32 e_flags; + u16 e_ehsize; + u16 e_phentsize; + u16 e_phnum; + u16 e_shentsize; + u16 e_shnum; + u16 e_shtrndx; +} Elf32_Ehdr; + +typedef struct { + u32 p_type; + u32 p_offset; + void *p_vaddr; + void *p_paddr; + u32 p_filesz; + u32 p_memsz; + u32 p_flags; + u32 p_align; +} Elf32_Phdr; + +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 + +#endif diff --git a/stub/hollywood.h b/stub/hollywood.h new file mode 100644 index 0000000..ad6924f --- /dev/null +++ b/stub/hollywood.h @@ -0,0 +1,31 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + Hollywood register definitions + +Copyright (C) 2008, 2009 Haxx Enterprises +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2008, 2009 John Kelley + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __HOLLYWOOD_H__ +#define __HOLLYWOOD_H__ + +/* Hollywood Registers */ + +#define HW_REG_BASE 0xd800000 +#define HW_TIMER (HW_REG_BASE + 0x010) +#define HW_IRQENABLE (HW_REG_BASE + 0x03c) +#define HW_MEMMIRR (HW_REG_BASE + 0x060) +#define HW_GPIO1ENABLE (HW_REG_BASE + 0x0dc) +#define HW_GPIO1OUT (HW_REG_BASE + 0x0e0) +#define HW_GPIO1DIR (HW_REG_BASE + 0x0e4) +#define HW_GPIO1IN (HW_REG_BASE + 0x0e8) +#define HW_GPIO1INTLVL (HW_REG_BASE + 0x0ec) +#define HW_GPIO1INTFLAG (HW_REG_BASE + 0x0f0) +#define HW_GPIO1OWNER (HW_REG_BASE + 0x0fc) + +#endif diff --git a/stub/start.S b/stub/start.S new file mode 100644 index 0000000..f476c35 --- /dev/null +++ b/stub/start.S @@ -0,0 +1,144 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + system startup + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +.arm + +.extern _main +.extern __got_start +.extern __got_end +.extern __bss_start +.extern __bss_end +.extern __stack_addr +.globl _start +.globl debug_output + + +.section .init + +_start: + @ Get real address of _start + sub r4, pc, #8 + @ Subtract offset to get the address that we were loaded at + ldr r0, =_start + sub r4, r4, r0 + @ Output 0x42 to the debug port + mov r0, #0x42 + bl debug_output + + @ Set up a stack + ldr sp, =__stack_addr + add sp, r4 + + @ perform boot2v3 memory controller poke + bl memctrl_do_sub_sub_poke + + @ Output 0x43 to the debug port + mov r0, #0x43 + bl debug_output + + @ check for a previous GOT relocation + ldr r1, [pc, #_is_reloced - . - 8] + cmp r1, #0 + bne done_got + + @ relocate the GOT entries + ldr r1, =__got_start + add r1, r4 + ldr r2, =__got_end + add r2, r4 +got_loop: + @ check for the end + cmp r1, r2 + beq done_got + @ read the GOT entry + ldr r3, [r1] + @ add our base address + add r3, r4 + str r3, [r1] + @ move on + add r1, r1, #4 + b got_loop + +done_got: + + @ note that we have already reloced GOT + mov r1, #1 + str r1, [pc, #_is_reloced - . - 8] + + @ clear BSS + ldr r1, =__bss_start + add r1, r4 + ldr r2, =__bss_end + add r2, r4 + mov r3, #0 +bss_loop: + @ check for the end + cmp r1, r2 + beq done_bss + @ clear the word and move on + str r3, [r1] + add r1, r1, #4 + b bss_loop + +done_bss: + mov r0, #0x44 + bl debug_output + @ take the plunge + mov r0, r4 + bl _main + @ _main returned! Go to whatever address it returned... + mov r1, r0 + mov r0, r4 + mov pc, r1 + +_is_reloced: + .long 0 + +memctrl_do_sub_sub_poke: + stmdb sp!, {lr} + ldr r0, =0x163 @ reg_address + mov r1, #0x4C @ address + bl memctrl_sub_poke + ldr r0, =0x163 @ read address back (flush?) + bl memctrl_sub_peek + ldr r0, =0x162 @ reg_data + mov r1, #1 @ data + bl memctrl_sub_poke + ldmia sp!, {pc} + +memctrl_sub_poke: + ldr r2, =0xD8B4000 + strh r0, [r2, #0x74] @ reg_address <= address + ldrh r0, [r2, #0x74] @ read reg_address back + strh r1, [r2, #0x76] @ reg_data <= data + mov pc, lr + +memctrl_sub_peek: + ldr r2, =0xD8B4000 + strh r0, [r2, #0x74] @ reg_address <= address + ldrh r0, [r2, #0x74] @ read reg_address back + ldrh r0, [r2, #0x76] @ data <= reg_data + mov pc, lr + +.pool + +debug_output: + @ load address of port + mov r3, #0xd800000 + @ load old value + ldr r2, [r3, #0xe0] + @ clear debug byte + bic r2, r2, #0xFF0000 + @ insert new value + and r0, r0, #0xFF + orr r2, r2, r0, LSL #16 + @ store back + str r2, [r3, #0xe0] + mov pc, lr diff --git a/stub/start.h b/stub/start.h new file mode 100644 index 0000000..f64a0b7 --- /dev/null +++ b/stub/start.h @@ -0,0 +1,18 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + system startup + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __START_H__ +#define __START_H__ + +#include "types.h" + +void debug_output(u8 byte); + +#endif diff --git a/stub/stub.c b/stub/stub.c new file mode 100644 index 0000000..a348f03 --- /dev/null +++ b/stub/stub.c @@ -0,0 +1,116 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + ELF loader stub + +Copyright (C) 2008, 2009 Haxx Enterprises +Copyright (C) 2008, 2009 Sven Peter +Copyright (C) 2008, 2009 Hector Martin "marcan" +Copyright (C) 2009 Andre Heider "dhewg" +Copyright (C) 2009 John Kelley + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "types.h" +#include "utils.h" +#include "start.h" +#include "hollywood.h" +#include "elf.h" + +typedef struct { + u32 hdrsize; + u32 loadersize; + u32 elfsize; + u32 argument; +} ioshdr; + +static inline void _memcpy(void *dst, const void *src, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + ((unsigned char *)dst)[i] = ((unsigned char *)src)[i]; +} + +static inline int memcmp(const char *s1, const u8 *s2, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + if (s1[i] != s2[i]) return s1[i] - s2[i]; + + return 0; +} + +void *loadelf(const u8 *elf) { + if(memcmp("\x7F" "ELF\x01\x02\x01",elf,7)) { + panic(0xE3); + } + + Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf; + if(ehdr->e_phoff == 0) { + panic(0xE4); + } + int count = ehdr->e_phnum; + Elf32_Phdr *phdr = (Elf32_Phdr*)(elf + ehdr->e_phoff); + while(count--) + { + if(phdr->p_type == PT_LOAD) { + const void *src = elf + phdr->p_offset; + _memcpy(phdr->p_paddr, src, phdr->p_filesz); + } + phdr++; + } + return ehdr->e_entry; +} + +static inline void mem_setswap(void) +{ + u32 d = read32(HW_MEMMIRR); + if(!(d & 0x20)) + write32(HW_MEMMIRR, d | 0x20); +} + +extern const u8 bootmii_elf[]; +extern const u8 bootmii_elf_end[]; +extern const u32 bootmii_elf_size; + +#define GP_POWER 0x000001 + +void *_main(void *base) +{ + ioshdr *hdr = (ioshdr*)base; + u8 *elf; + void *entry; + + elf = (u8*) base; + elf += hdr->hdrsize + hdr->loadersize; + + debug_output(0xF1); + mem_setswap(); + + write32(HW_IRQENABLE, 0); + + set32(HW_GPIO1ENABLE, GP_POWER); + clear32(HW_GPIO1DIR, GP_POWER); + clear32(HW_GPIO1OWNER, GP_POWER); + set32(HW_GPIO1INTLVL, GP_POWER); + udelay(1000); + set32(HW_GPIO1INTFLAG, GP_POWER); + udelay(400000); + if(read32(HW_GPIO1INTFLAG) & GP_POWER) { + debug_output(0xC0); + loadelf(elf); + debug_output(0xC1); + return (void *) 0xFFFF0000; + } + + // NOTE: END CRITICAL ZONE + + debug_output(0xF2); + entry = loadelf(bootmii_elf); + debug_output(0xF3); + + return entry; +} diff --git a/stub/stub.ld b/stub/stub.ld new file mode 100644 index 0000000..4ba674c --- /dev/null +++ b/stub/stub.ld @@ -0,0 +1,108 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + ELF loader stub linker script + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +OUTPUT_FORMAT("elf32-bigarm") +OUTPUT_ARCH(arm) +EXTERN(_start) +ENTRY(_start) + +__base_addr = 0; + +SECTIONS +{ + . = __base_addr; + .header : + { + __header = .; + /* Entry point (offset) */ + LONG(__code_start); + /* Loader size */ + LONG(__loader_size); + /* ELF size */ + LONG(0); + /* Boot argument? */ + LONG(0); + . = ALIGN(16); + } + + __code_start = .; + + .init : + { + *(.init) + . = ALIGN(4); + } + + .got : + { + __got_start = .; + *(.got.*) + *(.got) + . = ALIGN(4); + __got_end = . ; + } + + .text : + { + *(.text) + *(.text.*) + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + } + + __text_end = . ; + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + . = ALIGN(4); + } + + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + } + + .bss : + { + __bss_start = . ; + *(.dynbss) + *(.gnu.linkonce.b*) + *(.bss*) + *(.sbss*) + *(COMMON) + . = ALIGN(32); + __bss_end = . ; + } + +} + +__stack_end = (__bss_end); +__stack_addr = (__bss_end + 0x100); + +__end = __stack_addr ; +__loader_size = __end - __code_start; + +PROVIDE (__stack_end = __stack_end); +PROVIDE (__stack_addr = __stack_addr); +PROVIDE (__got_start = __got_start); +PROVIDE (__got_end = __got_end); +PROVIDE (__bss_start = __bss_start); +PROVIDE (__bss_end = __bss_end); diff --git a/stub/types.h b/stub/types.h new file mode 100644 index 0000000..4118d80 --- /dev/null +++ b/stub/types.h @@ -0,0 +1,38 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + types, memory areas, etc + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __TYPES_H__ +#define __TYPES_H__ + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef unsigned long long u64; + +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; + +typedef volatile unsigned char vu8; +typedef volatile unsigned short vu16; +typedef volatile unsigned int vu32; +typedef volatile unsigned long long vu64; + +typedef volatile signed char vs8; +typedef volatile signed short vs16; +typedef volatile signed int vs32; +typedef volatile signed long long vs64; + +typedef s32 size_t; + +#define NULL ((void *)0) + +#endif diff --git a/stub/utils.c b/stub/utils.c new file mode 100644 index 0000000..bbc8d58 --- /dev/null +++ b/stub/utils.c @@ -0,0 +1,31 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + random utilities + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#include "types.h" +#include "utils.h" +#include "hollywood.h" +#include "start.h" + +void delay(u32 d) +{ + write32(HW_TIMER, 0); + while(read32(HW_TIMER) < d); +} + +void panic(u8 v) +{ + while(1) { + debug_output(v); + udelay(500000); + debug_output(0); + udelay(500000); + } +} + diff --git a/stub/utils.h b/stub/utils.h new file mode 100644 index 0000000..2c32d72 --- /dev/null +++ b/stub/utils.h @@ -0,0 +1,177 @@ +/* + bootmii - a Free Software replacement for the Nintendo/BroadOn boot2. + random utilities + +Copyright (C) 2008, 2009 Hector Martin "marcan" + +# This code is licensed to you under the terms of the GNU GPL, version 2; +# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +*/ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +static inline u32 read32(u32 addr) +{ + u32 data; + __asm__ volatile ("ldr\t%0, [%1]" : "=r" (data) : "r" (addr)); + return data; +} + +static inline void write32(u32 addr, u32 data) +{ + __asm__ volatile ("str\t%0, [%1]" : : "r" (data), "r" (addr)); +} + +static inline u32 set32(u32 addr, u32 set) +{ + u32 data; + __asm__ volatile ( + "ldr\t%0, [%1]\n" + "\torr\t%0, %2\n" + "\tstr\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set) + ); + return data; +} + +static inline u32 clear32(u32 addr, u32 clear) +{ + u32 data; + __asm__ volatile ( + "ldr\t%0, [%1]\n" + "\tbic\t%0, %2\n" + "\tstr\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (clear) + ); + return data; +} + + +static inline u32 mask32(u32 addr, u32 clear, u32 set) +{ + u32 data; + __asm__ volatile ( + "ldr\t%0, [%1]\n" + "\tbic\t%0, %3\n" + "\torr\t%0, %2\n" + "\tstr\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set), "r" (clear) + ); + return data; +} + +static inline u16 read16(u32 addr) +{ + u32 data; + __asm__ volatile ("ldrh\t%0, [%1]" : "=r" (data) : "r" (addr)); + return data; +} + +static inline void write16(u32 addr, u16 data) +{ + __asm__ volatile ("strh\t%0, [%1]" : : "r" (data), "r" (addr)); +} + +static inline u16 set16(u32 addr, u16 set) +{ + u16 data; + __asm__ volatile ( + "ldrh\t%0, [%1]\n" + "\torr\t%0, %2\n" + "\tstrh\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set) + ); + return data; +} + +static inline u16 clear16(u32 addr, u16 clear) +{ + u16 data; + __asm__ volatile ( + "ldrh\t%0, [%1]\n" + "\tbic\t%0, %2\n" + "\tstrh\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (clear) + ); + return data; +} + + +static inline u16 mask16(u32 addr, u16 clear, u16 set) +{ + u16 data; + __asm__ volatile ( + "ldrh\t%0, [%1]\n" + "\tbic\t%0, %3\n" + "\torr\t%0, %2\n" + "\tstrh\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set), "r" (clear) + ); + return data; +} + +static inline u8 read8(u32 addr) +{ + u32 data; + __asm__ volatile ("ldrb\t%0, [%1]" : "=r" (data) : "r" (addr)); + return data; +} + +static inline void write8(u32 addr, u8 data) +{ + __asm__ volatile ("strb\t%0, [%1]" : : "r" (data), "r" (addr)); +} + +static inline u8 set8(u32 addr, u8 set) +{ + u8 data; + __asm__ volatile ( + "ldrb\t%0, [%1]\n" + "\torr\t%0, %2\n" + "\tstrb\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set) + ); + return data; +} + +static inline u8 clear8(u32 addr, u8 clear) +{ + u8 data; + __asm__ volatile ( + "ldrb\t%0, [%1]\n" + "\tbic\t%0, %2\n" + "\tstrb\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (clear) + ); + return data; +} + + +static inline u8 mask8(u32 addr, u8 clear, u8 set) +{ + u8 data; + __asm__ volatile ( + "ldrb\t%0, [%1]\n" + "\tbic\t%0, %3\n" + "\torr\t%0, %2\n" + "\tstrb\t%0, [%1]" + : "=&r" (data) + : "r" (addr), "r" (set), "r" (clear) + ); + return data; +} + +#define udelay(x) delay((x) * 19 / 10) +void delay(u32 d); +void panic(u8 v); + +#endif