diff -urN u-boot-86xx/MAKEALL u-boot-86xx-kuro_clean/MAKEALL --- u-boot-86xx/MAKEALL 2006-10-13 00:27:12.000000000 +0200 +++ u-boot-86xx-kuro_clean/MAKEALL 2006-11-06 22:13:16.000000000 +0100 @@ -106,9 +106,9 @@ LIST_824x=" \ A3000 barco BMW CPC45 \ CU824 debris eXalion HIDDEN_DRAGON \ - MOUSSE MUSENKI MVBLUE \ - OXC PN62 Sandpoint8240 Sandpoint8245 \ - sbc8240 SL8245 utx8245 \ + linkstation linkstationhg MOUSSE MUSENKI \ + MVBLUE OXC PN62 Sandpoint8240 \ + Sandpoint8245 sbc8240 SL8245 utx8245 \ " ######################################################################### diff -urN u-boot-86xx/Makefile u-boot-86xx-kuro_clean/Makefile --- u-boot-86xx/Makefile 2006-10-13 00:27:12.000000000 +0200 +++ u-boot-86xx-kuro_clean/Makefile 2006-11-06 22:15:20.000000000 +0100 @@ -122,7 +122,7 @@ CROSS_COMPILE = else ifeq ($(ARCH),ppc) -CROSS_COMPILE = powerpc-linux- +CROSS_COMPILE = ppc_6xx- endif ifeq ($(ARCH),arm) CROSS_COMPILE = arm-linux- @@ -237,6 +237,40 @@ all: $(ALL) +LSMODEL := $(shell head -n 1 include/config.h) + +linkstation_HGLAN_RAM: include/config.h + @[ -n "$(findstring HGLAN_RAM, $(LSMODEL))" ] || \ + { echo "Bad configuration: $(LSMODEL)" ; \ + exit 1 ; \ + } + @make all + @mv u-boot.bin u-boot-hg.ram.bin + +linkstation_HGLAN: include/config.h + @[ -n "$(findstring HGLAN_ROM, $(LSMODEL))" ] || \ + { echo "Bad configuration: $(LSMODEL)" ; \ + exit 1 ; \ + } + @make all + @mv u-boot.bin u-boot-hg.flash.bin + +linkstation_HDLAN_RAM: include/config.h + @[ -n "$(findstring HDLAN_RAM, $(LSMODEL))" ] || \ + { echo "Bad configuration: $(LSMODEL)" ; \ + exit 1 ; \ + } + @make all + @mv u-boot.bin u-boot-hd.ram.bin + +linkstation_HDLAN: include/config.h + @[ -n "$(findstring HDLAN_ROM, $(LSMODEL))" ] || \ + { echo "Bad configuration: $(LSMODEL)" ; \ + exit 1 ; \ + } + @make all + @mv u-boot.bin u-boot-hd.flash.bin + $(obj)u-boot.hex: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ @@ -317,6 +351,10 @@ ######################################################################### else +linkstation_HGLAN_RAM \ +linkstation_HGLAN \ +linkstation_HDLAN_RAM \ +linkstation_HDLAN \ all $(obj)u-boot.hex $(obj)u-boot.srec $(obj)u-boot.bin \ $(obj)u-boot.img $(obj)u-boot.dis $(obj)u-boot \ $(SUBDIRS) version gdbtools updater env depend \ @@ -1262,6 +1300,38 @@ kvme080_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc824x kvme080 etin +linkstation_HGLAN_RAM_config: mrproper + @>include/config.h ; \ + echo "/* HGLAN_RAM */" >>include/config.h ; \ + echo "#define CONFIG_HGLAN 1" >>include/config.h ; \ + echo "TEXT_BASE = 0x07F00000" >board/linkstation/config.tmp ; \ + ./mkconfig -a linkstation ppc mpc824x linkstation ; \ + echo "LinkStation HGLAN -- RAM BUILD ..." + +linkstation_HGLAN_config: mrproper + @>include/config.h ; \ + echo "/* HGLAN_ROM */" >>include/config.h ; \ + echo "#define CONFIG_HGLAN 1" >>include/config.h ; \ + echo "TEXT_BASE = 0xFFF00000" >board/linkstation/config.tmp ; \ + ./mkconfig -a linkstation ppc mpc824x linkstation ; \ + echo "LinkStation HGLAN -- ROM BUILD ..." + +linkstation_HDLAN_RAM_config: mrproper + @>include/config.h ; \ + echo "/* HDLAN_RAM */" >>include/config.h ; \ + echo "#define CONFIG_HLAN 1" >>include/config.h ; \ + echo "TEXT_BASE = 0x03F00000" >board/linkstation/config.tmp ; \ + ./mkconfig -a linkstation ppc mpc824x linkstation ; \ + echo "LinkStation HDLAN -- RAM BUILD ..." + +linkstation_HDLAN_config: mrproper + @>include/config.h ; \ + echo "/* HDLAN_ROM */" >>include/config.h ; \ + echo "#define CONFIG_HLAN 1" >>include/config.h ; \ + echo "TEXT_BASE = 0xFFF00000" >board/linkstation/config.tmp ; \ + ./mkconfig -a linkstation ppc mpc824x linkstation ; \ + echo "LinkStation HDLAN -- ROM BUILD ..." + MOUSSE_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc824x mousse diff -urN u-boot-86xx/board/linkstation/INSTALL u-boot-86xx-kuro_clean/board/linkstation/INSTALL --- u-boot-86xx/board/linkstation/INSTALL 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/INSTALL 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,631 @@ + + Installing U-Boot for LinkStation + + For U-Boot port version 2.1.0 + 16 September 2006 + + Copyright (c) 2006 Mihai Georgian + + Permission is granted to copy, distribute and/or modify this document under + the terms of the [1]GNU Free Documentation License, Version 1.2 or any later + version published by the Free Software Foundation; with no Invariant + Sections, no Front-Cover Texts, and no Back-Cover Texts. The full text of + the license can be obtained by clicking on the above link. + + No liability for the contents of this document can be accepted. The + information in this document is provided in good faith but no warranty can + be made for its accuracy and the author does not take any responsibility. + Use the concepts, examples and information at your own risk. There may be + errors and inaccuracies, that could be damaging to your system. + + Use of a term in this document should not be regarded as affecting the + validity of any trademark or service mark. Naming of particular products or + brands should not be seen as endorsements. + _________________________________________________________________ + + WARNING + + Flashing the LinkStation with unauthorised firmare voids your warranty. When + installing firmware on an embedded computer things can and, sometimes, do go + wrong. The power can go down in the middle of the flash operation or the + flash write can fail rendering your LinkStation unusable. Please read this + entire page carefully before attempting to install U-Boot. + + If you are not prepared to lose your LinkStation, do not attempt to install + U-Boot + + Introduction + + U-Boot for the LinkStation is distributed as a source patch against + u-boot-1.1.4. To compile it you will need either a cross toolchain installed + on your PC or native development tools installed on your LinkStation. These + instructions assume that you are running Linux on a X86 PC and that you are + using a cross toolchain. + + To allow testing of U-Boot on your LinkStation without burning it into + flash, a kernel module named uloader.o is provided. Uloader allows you to + use Linux to load a RAM build of U-Boot and start it. The RAM build of + U-Boot is very close to the ROM build. The only differences are the absence + of the basic initialisation code (which cannot run from RAM) and the link + address. It is strongly recommended that you test U-Boot on your LinkStation + using a RAM build before building the ROM version and attempting to burn it + into flash. Once you have the RAM build up and running you can use it to + install (burn) the ROM version. + + Supported Hardware + + The LinkStation port of U-Boot described in this document supports the + following PowerPC based models: + 1. LinkStation version 1 (model HD-HLAN-1) + 2. KuroBox standard + 3. LinkStation HG (model HD-HGLAN) + 4. KuroBox HG + + This version of U-Boot will certainly not work on the the LinkStation + version 2 (model HD-HLAN-2) as the LinkStation version 2 is based on a MIPS + processor. The MIPS processor is completely different from the PowerPC + processor and attempting to flash a LinkStation version 2 with PowerPC + firmware it is guaranteed to make it completely unusable. + + Get telnet Access + + Try to connect to your LinkStation using telnet. If you see the telnet + command prompt, read [2]CGI Exploit (PowerPC) original method of Hacking the + LinkStation about how to get telnet access. + + If the above method doesn't work for you, read [3]Turn your LinkStation into + a Kuro Box (PowerPC) for other methods to get telnet access. + + The above methods do not work for the LinkStation HG. For this model, the + only solution is to load a telnet-enabled version of the firmware. Read the + pages about [4]OpenLink and the [5]firmware flasher + + You can also try to flash [6]a modified version of the original firmware. + + Install the Serial Console + + Installing the serial console is not an absolute requirement and it will + void your warranty. U-Boot can be installed and controlled without it. + However, the serial console will give you the best control over both U-Boot + and Linux. + + Read [7]Add a Serial port to the PowerPC Linkstation to learn how to install + the serial console. + + Install netcat (nc) + + If you haven't installed the serial console you will need to install netcat + (nc). Netcat is a networking utility which reads and writes data across + network connections, using the TCP/IP protocol. It comes standard with most + Linux distributions. For more information, visit the netcat home page + [8]http://netcat.sourceforge.net or [9]http://www.vulnwatch.org/netcat for + the Windows version. + + Get the ELDK + + If you don't have a cross toolchain installed, download the DENX Embedded + Linux Development Kit (ELDK) from + [10]http://ftp.sunet.se/pub/Linux/distributions/eldk/3.1.1/ppc-linux-x86/iso + /ppc-2005-03-07.iso, install it and spend some time getting familiar with + it. + + Preparation + + Create the build directory and set the environment variable UBOOT_BUILD to + the path to it + # mkdir + # export UBOOT_BUILD= + # cd $UBOOT_BUILD + Download the tarball for u-boot-1.1.4 from + [11]ftp://ftp.denx.de/pub/u-boot/u-boot-1.1.4.tar.bz2 + Download the LinkStation patch, [12]u-boot-1.1.4-list-2.1.0.diff.gz + Download the uloader module for your LinkStation / KuroBox model. + * For the LinkStation 1 / KuroBox standard, download + [13]uloader-2.4.17.tar.gz + * For the LinkStation HG / KuroBox HG, download [14]uloader-2.4.20.tar.gz + + Untar u-boot-1.1.4 and apply the patch. + # tar xjf u-boot-1.1.4.tar.bz2 + # cd u-boot-1.1.4 + # gunzip ../u-boot-1.1.4-list-2.01.diff.gz | patch -p1 + + Untar the uloader archive for your LinkStation / KuroBox model. The archive + contains the source code, a binary module compiled for the original + LinkStation kernel and a simple bash script to load and start a RAM build of + U-Boot. + + The binary in uloader-2.4.17.tar.gz has been compiled against + 2.4.17_mvl21-sandpoint. Use only on the LinkStation 1 / KuroBox standard. + The binary in uloader-2.4.20.tar.gz has been compiled against + 2.4.20_mvl31-ppc_linkstation. Use only on the LinkStation HG / KuroBog HG. + If you have a different kernel version, you may need to recompile the module + for your kernel. Compiling the module requires a fully configured kernel + source tree. It is recommended to use the same gcc version as the one used + to compile the kernel. There is a small but important difference between the + two uloader source archives. The difference is the U-Boot load address. If + you compile uloader for the LinkStation 1 / KuroBox standard, use the + sources in uloader-2.4.17.tar.gz. If you compile for the LinkStation HG / + KuroBox HG, use the sources in uloader-2.4.20.tar.gz. In both cases you + need to modify the Makefile to match your development environment. + + LinkStation 1 / KuroBox standard + # cd .. + # tar xzf uloader-2.4.17.tar.gz + # cd u-boot-1.1.4 + + LinkStation HG / KuroBox HG + # cd .. + # tar xzf uloader-2.4.20.tar.gz + # cd u-boot-1.1.4 + + Source your ELDK environment + # . /config_6xx + + Configure + + Edit include/configs/linkstation.h and set the following variables for your + environment: + + CONFIG_IPADDR_LS - the IP address of your LinkStation while running + U-Boot (mandatory). The default address is + 192.168.11.150. + CONFIG_SERVERIP_LS - the IP address of the NFS/TFTP/DHCP/BOOTP server, + normally the address of your Linux PC (mandatory). + The default address is 192.168.11.149. + CONFIG_NCIP_LS - the address of the computer running netcat (nc), + normally the address of your Linux PC (optional). + If the define is missing, CONFIG_NCIP_LS will be + set to the same value as CONFIG_SERVERIP_LS + + RAM Build + + For LinkStation 1 / KuroBox standard run: + make linkstation_HDLAN_RAM_config + make linkstation_HDLAN_RAM + + The name of the resulting binary is u-boot-hd.ram.bin + + For LinkStation HG / KuroBox HG run: + make linkstation_HGLAN_RAM_config + make linkstation_HGLAN_RAM + + The name of the resulting binary is u-boot-hg.ram.bin + + Net Console + + The net console is the U-Boot driver which uses the UDP protocol with a + default port of 6666 to send the console output to and receive the console + input from a remote computer. You need to run netcat on the remote computer + to communicate with the U-Boot net console. The communication is + bidirectional. Netcat will display on your screen the console output + received from U-Boot and will send your keyboard input back to U-Boot. + + If U-Boot cannot contact the remote computer, it switches the console to the + serial port. To show that it changed the console, U-Boot makes the HDD LED + blink with the pattern corresponding to the serial console (see The Reset + Button below). The timeout period is 20 sec. + + Minimal Console + + U-Boot for the LinkStation is designed to allow some control over the boot + process even in the absence of a console. For this, it uses the power button + (the big button at the front) and the reset button (the small red button at + the back). + + Before installing U-Boot, when the LinkStation is switched on, the power LED + starts blinking, the original boot loader starts executing and, very + quickly, it starts booting the kernel from flash. If U-Boot is installed, + the power LED will change from blinking quickly to blinking very slowly. The + blink pattern is the same as the one used to indicate sleep mode in normal + operation. When the power LED starts blinking slowly at boot, U-Boot has + taken over and it is counting down the boot delay before booting the kernel. + The default boot delay is 10 sec. From the moment when the power LED starts + blinking slowly and for the duration of the boot delay, you can control the + boot process with the power and reset buttons. + + The Power Button + + If you push the power button and keep it pressed for more than 1 sec, the + boot process will stop and the LinkStation will wait for a command. A + stopped boot process is indicated by the power LED being lit solid. The + effect is the same a pressing 's' on the console. + + A long push of the power button acts as a toggle. If the boot delay count + down is in progress, a long push of the power button stops the boot process. + If the boot process is stopped (U-Boot is at the command prompt, even if you + can't see it), a long push of the power button restarts the boot process + resetting the boot delay to its original value. The restart of the boot + process is indicated by the power LED blinking slowly. + + By default U-Boot supports three pre-configured boot commands: + 1. The first boot command will attempt to load and boot a file named + boot/vmlinux.UBoot from the first hard disk partition, /dev/hda1. The + file can be in any of the U-Boot bootable formats but uImage is the + preferred format. If the file is missing or corrupted, U-Boot will fall + back to booting the original kernel from flash. + 2. The second boot command will boot the original kernel from flash. + Please note that the original kernel for the LinkStation 1 / KuroBox + standard has a bug in the function that calibrates the decrementer and + it will stop for up to 180 sec during boot. This bug is not an U-Boot + bug but a kernel bug which is uncovered by the fact that U-Boot + activates the decrementer where the original boot loader does not. + The original kernel for LinkStation HG / KuroBox HG does not suffer from + the above problem. + 3. The third boot command will attempt to boot in emergency mode (EM). It + does this by passing the argument root=/dev/ram0 to the kernel. + LinkStation / LinkStation HG owners should avoid booting in EM mode as + the root password for this mode on the LinkStation is unknown. + The original kernel for the LinkStation / KuroBox standard and for some + of the earlier LinkStation HG / KuroBox HG models ignores the root + argument. These models will boot normally from the on-board flash when + the EM boot command is used. Read the section on EM mode if your + LinkStation HG / KuroBox HG has a kernel that doesn't boot in EM mode + using this boot command. + + You can cycle through the boot commands with the power button. + + To see which of the three commands U-Boot is going to execute, press the + power button quickly. The HDD LED (the third from the top) will start + blinking. The number of times the LED blinks, shows the number of the active + boot command. For example, a pattern short on - short off - short on - long + off, means that the boot command number 2 is active. U-Boot will repeat the + blinking cycle for a total duration of about 5 sec counting from the moment + the power button is released. + + A short press of the power button while the HDD LED is blinking will advance + the boot command to the next one. + + Changing the boot command does not change the boot status. If the boot is + stopped, it will not be restarted. If the boot is in progress, it will not + be stopped but the boot delay will be reset to the original value. + + The Reset Button + + Two consoles are currently configured, the serial console and the net + console. The first console is the serial console and the second console is + the net console (nc). The net console is the default console. + + The reset button can be used, similarly to the power button, to switch + consoles. A press on the reset button (here, it doesn't matter how long you + keep the button pressed) displays the currently active console using the HDD + LED. Repeatedly pressing the reset button while the HDD LED is blinking will + toggle between the two consoles. The blinking pattern is different from the + one showing the boot command. The pattern which shows that the second (net) + console is active is short off - short on - short off - long on. U-Boot will + repeat the blinking cycle for a total duration of about 5 sec counting from + the moment the reset button is released. + + Load and Test + + Mount the LinkStation SMB public share and copy the following files to it: + + For LinkStation 1 / KuroBox standard + # mount -t smbfs -o password="" ///share/mnt + # cp u-boot-hd.ram.bin /mnt + # cp ../uloader-2.4.17/uloader.o /mnt + # cp ../uloader-2.4.17/u-boot-load-hd.sh /mnt + # umount /mmt + + For LinkStation HG / KuroBox HG + # mount -t smbfs -o password="" ///share/mnt + # cp u-boot-hg.ram.bin /mnt + # cp ../uloader-2.4.20/uloader.o /mnt + # cp ../uloader-2.4.20/u-boot-load-hg.sh /mnt + # umount /mmt + + If you installed the serial port, open another window and use minicom to + connect to your LinkStation serial console. The serial port settings are + 57600,N,8, the same as the settings used by the original Linux kernel. + + Start netcat to communicate with the U-Boot net console. Open another window + and run board/linkstation/nc.sh. Nc.sh is a simple script which invokes + netcat with the correct options. To quit nc, press ^T (control-T). + # cd $UBOOT_BUILD/u-boot-1.1.4 + # board/linkstation/nc.sh + + Where is CONFIG_IPADDR_LS (see Configure U-Boot + above). When you run nc.sh nothing will be written to the screen. This is + normal as Linux is not using the net console. + + From your original window, use telnet to connect to the LinkStation and + launch U-Boot. Replace lshg in the example below with the name / IP address + of your LinkStation. Replace myroot with the login you created when you + gained telnet access. For LinkStation 1 / KuroBox standard, use + u-boot-load-hd.sh instead of u-boot-load-hg.sh. Type the commands shown in + bold. + # telnet lshg + Trying 192.168.0.58... + Connected to lshg. + Escape character is '^]'. + BUFFALO INC. Link Station series HD-HGLAN (IEMITSU) + HD-HGLAN6C5 login: myroot + Linux (none) 2.4.20_mvl31-ppc_linkstation #3 Thu May 19 13:34:18 JST 2005 + ppc unknown + root@HD-HGLAN6C5:~# cd /mnt/share + root@HD-HGLAN6C5:/mnt/share# ./u-boot-load-hg.sh + root@HD-HGLAN6C5:/mnt/share# exit + Connection closed by foreign host. + # + + If you have a serial console you should see the initial U-Boot startup + messages. Even if the default console is the net console, U-Boot still sends + the console output to the serial port until it initialises the network + controller. + U-Boot 1.1.4 LiSt 2.1.0 (Sep 12 2006 - 23:09:44) LinkStation HG / KuroBox HG + CPU: MPC8245 Revision 1.4 at 262.144 MHz: 16 kB I-Cache 16 kB D-Cache + DRAM: 128 MB + FLASH: 4 MB + *** Warning - bad CRC, using default environment + 00 0b 10ec 8169 0200 ff + 00 0c 1283 8212 0180 ff + 00 0e 1033 0035 0c03 ff + 00 0e 1033 0035 0c03 ff + 00 0e 1033 00e0 0c03 ff + Net: RTL8169#0 + + Watch the net console window. After a few seconds, time needed by U-Boot to + initialise the network controller and the IDE controller you should see the + U-Boot messages. + U-Boot 1.1.4 LiSt 2.1.0 (Sep 12 2006 - 23:09:44) LinkStation HG / KuroBox HG + IDE: Bus 0: OK + Device 0: Model: Maxtor 7Y250P0 Firm: YAR41BW0 Ser#: Y62W8PDE + Type: Hard Disk + Supports 48-bit addressing + Capacity: 239372.4 MB = 233.7 GB (490234752 x 512) + Boot in 10 seconds ('s' to stop)... + + Press 's' on your keyboard to stop the boot process. + + If you want to use the serial console, watch the power LED of your + LinkStation. When it starts blinking very slowly, use the power button to + stop the boot process. Wait for the power LED to go dim and press and hold + the power button until the LED lights up brightly indicating that the boot + process has stopped. Now press the reset button twice and you should see the + U-Boot command prompt (=>) in your minicom window. You can now control + U-Boot from the minicom window. + + Using u-boot-load-hd.sh / u-boot-load-hg.sh leads to the above results on + devices with the original software. On some LinkStations with modified + software, reboot has been modified to send a reboot command to the AVR. + This is indicated by the fast blinking of the power LED immediately after + running u-boot-load-hd.sh / u-boot-load-hg.sh. Once the AVR receives a + reboot command, the reboot process cannot be stopped. The AVR will reboot + the LinkStation 5 min after receiving the reboot command. + If you find yourself in the above situation you can still test U-Boot by + booting your LinkStation with the AVR disabled. Press and hold the reset + button and then press the power button. All LEDs will start flashing but + your LinkStation will boot normally. Now you can use the procedure + described above with one caveat: the AVR being disabled, pressing the + buttons will have no effect so you will not be able to test the behaviour + of the minimal console. + + Once you get the U-Boot command prompt, start testing it. Read the + [15]U-Boot documentation and try each command you are interested in. + + Keep in mind that U-Boot interprets all input number as hex numbers. If, for + example, you type 256, U-Boot will interpret it as 598 decimal. + + When you are testing memory write commands, do not attempt to write to the + first MB of memory (0x00000000 to 0x00100000) as you will be overwriting the + exception vectors and U-Boot will crash. + + An important command is flinfo which displays information about the flash + chip. If the information displayed is correct for your flash, test the flash + erase and flash write commands. To do this, you will need to find an empty + sector, one for which each byte is 0xFF. Hint: check the last flash sector + first, chances are that it's empty. When you are testing commands that write + to the flash, always remember that you can write a single byte but you can + only erase whole sectors. + + Be very careful not to write to the flash memory range 0xFFC00000 to + 0xFFF7FFFF. This area contains the Linux kernel, the initial RAM disk used + for EM mode, the bootloader and the configuration sector (which holds the + "OKOK" or "NGNG" pattern). The range 0xFFF80000 to 0xFFFFFFFF is the user + area and, in most cases, is empty. Always check using the U-Boot command md + (memory display) if the flash area you intend to use is empty (all bytes are + 0xFF). For more information about the flash organisation, read + [16]PPCFlashROM for the LinkStation 1 / KuroBox standard or [17]HGFlashROM + for the LinkStation HG / KuroBox HG. + + ROM Build + + Once you are happy with the RAM build, you are ready for the ROM build. + + For LinkStation 1 / KuroBox standard run: + make linkstation_HDLAN_config + make linkstation_HDLAN + + The name of the resulting binary is u-boot-hd.flash.bin + + For LinkStation HG / KuroBox HG run: + make linkstation_HGLAN_config + make linkstation_HGLAN + + The name of the resulting binary is u-boot-hg.flash.bin + + Install + + Do not attempt to flash from U-Boot if the power LED is blinking. Your + LinkStation is likely to reboot and you will end up with a "brick" + Test the flash commands thoroughly before deciding to burn U-Boot into + flash. Write at least 128 kB to the flash to test potential timeout + problems + The flash routines in this version of U-Boot for the LinkStation should be + able to identify and handle any CFI flash which uses the AMD standard + command set. However, they were tested only on a LinkStation with a Fujitsu + MBM29PL32TM flash chip and on a LinkStation HG with a ST Micro M29DW324DB + flash chip. + Be very careful not to flash your hardware with the wrong U-Boot build. + Flashing any RAM build or flashing a ROM build for the LinkStation 1 / + KuroBox standard into the LinkStation HG / KuroBox HG or viceversa will + "brick" your device. This is especially true if you are flashing from Linux + as U-Boot has safety checks to avoid flashing the wrong build. + + Flashing U-Boot from U-Boot + + The RAM build of U-Boot can be used to load and flash the ROM build. This is + the preferred method. + + Boot your LinkStation normally. Open a telnet session and create a directory + to hold the U-Boot flash image. + root@linkstation:~# cd /mnt/share + root@linkstation:/mnt/share# mkdir u-boot + + Copy the U-Boot flash image to your LinkStation SMB share in the directory + u-boot. + + Load the RAM build of U-Boot and at the U-Boot command prompt type: + => run upgrade + + U-Boot will attempt to load the ROM build from the directory share/u-boot/ + on the third partition of the hard drive. If the load is successful, it will + do the following: + 1. unprotect the bootloader area; + 2. erase the bootloader area; + 3. copy the loaded file to the bootloader area; + 4. verify the copy; + + Here is the output of run upgrade + => run upgrade + Loading 0:3:share/u-boot/u-boot-hg.flash.bin + 174668 bytes read + Un-Protected 3 sectors + Flash erase: first = 55 @ 0xfff00000 + last = 57 @ 0xfff20000 + Flash erase: Done + Erased 3 sectors + Copy to Flash... done + Total of 174668 bytes were the same + => + + When the above sequence finishes, U-Boot returns to the command prompt (=>). + + Depending on your flash chip, the flash operation can take a long time. Wait + patiently and do not try to power down or otherwise interrupt the flash or + you will end up with a "brick". + + Reboot: + => reset + + The power LED should start blinking slowly and, if you have a serial + console, you should see the U-Boot startup messages. Your LinkStation is now + running U-Boot. + + Flashing U-Boot from Linux + + Connect to your LinkStation using either the serial port or telnet. + + For LinkStation 1 / KuroBox standard run: + # cd /mnt/share/u-boot + # dd if=u-boot-hd.flash.bin of=/dev/fl2 bs=1k + # cmp u-boot.bin /dev/fl2 + + For LinkStation HG / KuroBox HG run: + # cd /mnt/share/u-boot + # dd if=u-boot-hg.flash.bin of=/dev/mtd1 bs=1k + # cmp u-boot.bin /dev/mtd1 + + The above commands for LinkStation HG / KuroBox HG will work on devices with + the original kernel version 2.4.20 but might to work on earlier devices + using kernel version 2.4.17. Please check which device corresponds to the + bootloader partition on your hardware. + + If the Flash Fails + + If the flash was not written correctly but U-Boot returns at the command + prompt, try to re-run run upgrade. + + If the same happens when you attempt to install U-Boot from Linux, try to dd + again. + + If your flash fails completely, for example due to a power failure, all is + not completely lost. You can still use a JTAG cable to re-flash your + Linkstation. Unfortunately, this is a relatively complicated and expensive + solution as it involves acquiring or building the JTAG cable and soldering + the header for it on the LinkStation motherboard. For more information on + how to use a JTAG cable with the LinkStation you can visit + [18]www.linkstationwiki.net and [19]www.kurobox.com/mwiki. + + EM Mode + + Warning for the LinkStation / LinkStation HG users + + Do not attempt to boot into EM mode using the method described here. The + password for the EM mode is unknown for all LinkStation models. + + Once you have U-Boot installed in the on-board flash, you can boot in EM + mode even if the third boot command described above doesn't work. + + Stop the boot countdown by pressing 's' in your net console window and, at + the U-Boot command prompt, run: + => run writeng + => run flboot + + The above commands write "NGNG" to 0xFFF70000 and boot from the on-board + flash. To revert to normal boot by writing "OKOK" to 0xFFF70000, run: + => run writeok + => boot + + Advanced configuration + + The initial U-Boot configuration can be changed by editing the file + include/configs/linkstation.h. + + In all the examples below, please note the backslash-zero (\0) at the end of + the strings and the space-backslash ( \) at the end of each lines and do not + change them. + + Change the name of the default boot file + + Search for the lines containing: + "hdpart=0:1\0" \ + "hdfile=boot/vmlinux.UBoot\0" \ + + and change them to the values you want. Partition 0:1 means disk 0, + partition 1. Obviously, you can only change the partition number as there is + only one disk. The name of the file must be given relative to the root of + the partition. + + Change the default console to the serial console + + Search for the lines containing: + "stdin=nc\0" \ + "stdout=nc\0" \ + "stderr=nc\0" \ + + and change them to: + "stdin=serial\0" \ + "stdout=serial\0" \ + "stderr=serial\0" \ + + Change the default boot command to boot from flash + + Search for the lines containing: + "bootcmd1=run hdboot;run flboot\0" \ + "bootcmd2=run flboot\0" \ + + and change them to: + "bootcmd1=run flboot\0" \ + "bootcmd2=run hdboot;run flboot\0" \ + +References + + 1. http://www.linuxnotincluded.org.uk/fdl.txt + 2. http://www.linkstationwiki.net/index.php?title=CGI_Exploit_%28PowerPC%29_original_method_of_Hacking_the_LinkStation + 3. http://www.linkstationwiki.net/index.php?title=Turn_your_LinkStation_into_a_Kuro_Box_%28PowerPC%29 + 4. http://linkstationwiki.net/index.php?title=OpenLink + 5. http://linkstationwiki.net/index.php?title=The_LinkStation_firmware_flasher + 6. http://downloads.linkstationwiki.net/snapshots/HD-HGLAN_149_100_telnet.zip + 7. http://www.linkstationwiki.net/index.php?title=Add_a_Serial_port_to_the_PowerPC_Linkstation + 8. http://netcat.sourceforge.net/ + 9. http://www.vulnwatch.org/netcat + 10. http://ftp.sunet.se/pub/Linux/distributions/eldk/3.1.1/ppc-linux-x86/iso/ppc-2005-03-07.iso + 11. ftp://ftp.denx.de/pub/u-boot/u-boot-1.1.4.tar.bz2 + 12. http://www.linuxnotincluded.org.uk/linkstation/downloads/u-boot-1.1.4-list-2.1.0.diff.gz + 13. http://www.linuxnotincluded.org.uk/linkstation/downloads/uloader-2.4.17.tar.gz + 14. http://www.linuxnotincluded.org.uk/linkstation/downloads/uloader-2.4.20.tar.gz + 15. http://www.denx.de/wiki/DULG/Manual + 16. http://linkstationwiki.net/index.php?title=Information/PPCFlashROM + 17. http://linkstationwiki.net/index.php?title=Information/HGFlashROM + 18. http://www.linkstationwiki.net/ + 19. http://www.kurobox.com/mwiki diff -urN u-boot-86xx/board/linkstation/Makefile u-boot-86xx-kuro_clean/board/linkstation/Makefile --- u-boot-86xx/board/linkstation/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/Makefile 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,41 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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 +# + +include $(TOPDIR)/config.mk + +LIB = lib$(BOARD).a + +OBJS = $(BOARD).o flash.o ide.o hwctl.o bootls.o avr.o +SOBJS = early_init.o + +$(LIB): .depend $(OBJS) $(SOBJS) + $(AR) crv $@ $(OBJS) $(SOBJS) + +######################################################################### + +.depend: Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) + $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff -urN u-boot-86xx/board/linkstation/avr.c u-boot-86xx-kuro_clean/board/linkstation/avr.c --- u-boot-86xx/board/linkstation/avr.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/avr.c 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,307 @@ +/* + * avr.c + * + * AVR functions + * + * Copyright (C) 2006 Mihai Georgian + * + * 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 + */ +#include +#include +#include + +/* Button codes from the AVR */ +#define PWRR 0x20 /* Power button release */ +#define PWRP 0x21 /* Power button push */ +#define RESR 0x22 /* Reset button release */ +#define RESP 0x23 /* Reset button push */ +#define AVRINIT 0x33 /* Init complete */ +#define AVRRESET 0x31 /* Reset request */ + +/* LED commands */ +#define PWRBLINKSTRT '[' /* Blink power LED */ +#define PWRBLINKSTOP 'Z' /* Solid power LED */ +#define HDDLEDON 'W' /* HDD LED on */ +#define HDDLEDOFF 'V' /* HDD LED off */ +#define HDDBLINKSTRT 'Y' /* HDD LED start blink */ +#define HDDBLINKSTOP 'X' /* HDD LED stop blink */ + +/* Timings for LEDs blinking to show choice */ +#define PULSETIME 250 /* msecs */ +#define LONGPAUSE (5 * PULSETIME) + +/* Button press times */ +#define PUSHHOLD 1000 /* msecs */ +#define NOBUTTON (6 * (LONGPAUSE+PULSETIME)) + +/* Boot and console choices */ +#define MAX_BOOT_CHOICE 3 + +static char *consoles[] = { + "serial", +#if defined(CONFIG_NETCONSOLE) + "nc", +#endif +}; +#define MAX_CONS_CHOICE (sizeof(consoles)/sizeof(char *)) + +#if !defined(CONFIG_NETCONSOLE) +#define DEF_CONS_CHOICE 0 +#else +#define DEF_CONS_CHOICE 1 +#endif + +#define perror(fmt,args...) printf("%s: ",__FUNCTION__);printf(fmt,##args) + +extern void miconCntl_SendCmd(unsigned char dat); +extern void miconCntl_DisWDT(void); + +static int boot_stop; + +static int boot_choice = 1; +static int cons_choice = DEF_CONS_CHOICE; + +static char envbuffer[16]; + +void init_AVR_DUART (void) +{ + NS16550_t AVR_port = (NS16550_t) CFG_NS16550_COM2; + int clock_divisor = CFG_NS16550_CLK / 16 / 9600; + + /* + * AVR port init sequence taken from + * the original Linkstation init code + * Normal U-Boot serial reinit doesn't + * work because the AVR uses even parity + */ + AVR_port->lcr = 0x00; + AVR_port->ier = 0x00; + AVR_port->lcr = LCR_BKSE; + AVR_port->dll = clock_divisor & 0xff; + AVR_port->dlm = (clock_divisor >> 8) & 0xff; + AVR_port->lcr = LCR_WLS_8 | LCR_PEN | LCR_EPS; + AVR_port->mcr = 0x00; + AVR_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR; + + miconCntl_DisWDT(); + + boot_stop = 0; + miconCntl_SendCmd(PWRBLINKSTRT); +} + +void hw_watchdog_reset (void) +{ +} + +static inline int avr_tstc(void) +{ + return (NS16550_tstc((NS16550_t)CFG_NS16550_COM2)); +} + +static inline char avr_getc(void) +{ + return (NS16550_getc((NS16550_t)CFG_NS16550_COM2)); +} + +static int push_timeout(char button_code) +{ + ulong push_start = get_timer(0); + while (get_timer(push_start) <= PUSHHOLD) + if (avr_tstc() && avr_getc() == button_code) + return 0; + return 1; +} + +static void next_boot_choice(void) +{ + ulong return_start; + ulong pulse_start; + int on_times; + int button_on; + int led_state; + char c; + + button_on = 0; + return_start = get_timer(0); + + on_times = boot_choice; + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + pulse_start = get_timer(0); + + while (get_timer(return_start) <= NOBUTTON || button_on) + { + if (avr_tstc()) { + c = avr_getc(); + if (c == PWRP) + button_on = 1; + else if (c == PWRR) { + button_on = 0; + return_start = get_timer(0); + if (++boot_choice > MAX_BOOT_CHOICE) + boot_choice = 1; + sprintf(envbuffer, "bootcmd%d", boot_choice); + if (getenv(envbuffer)) { + sprintf(envbuffer, "run bootcmd%d", boot_choice); + setenv("bootcmd", envbuffer); + } + on_times = boot_choice; + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + pulse_start = get_timer(0); + } else { + perror("Unexpected code: 0x%02X\n", c); + } + } + if (on_times && get_timer(pulse_start) > PULSETIME) { + if (led_state == 1) { + --on_times; + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + } else { + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + } + pulse_start = get_timer(0); + } + if (!on_times && get_timer(pulse_start) > LONGPAUSE) { + on_times = boot_choice; + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + pulse_start = get_timer(0); + } + } + if (led_state) + miconCntl_SendCmd(HDDLEDOFF); +} + +void next_cons_choice(int console) +{ + ulong return_start; + ulong pulse_start; + int on_times; + int button_on; + int led_state; + char c; + device_t *idev; + device_t *odev; + + button_on = 0; + cons_choice = console; + return_start = get_timer(0); + + on_times = cons_choice+1; + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + pulse_start = get_timer(0); + + while (get_timer(return_start) <= NOBUTTON || button_on) + { + if (avr_tstc()) { + c = avr_getc(); + if (c == RESP) + button_on = 1; + else if (c == RESR) { + button_on = 0; + return_start = get_timer(0); + cons_choice = (cons_choice + 1) % MAX_CONS_CHOICE; + idev = search_device(DEV_FLAGS_INPUT, consoles[cons_choice]); + odev = search_device(DEV_FLAGS_OUTPUT, consoles[cons_choice]); + console_setfile (stdin, idev); + console_setfile (stdout, odev); + console_setfile (stderr, odev); + on_times = cons_choice+1; + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + pulse_start = get_timer(0); + } else { + perror("Unexpected code: 0x%02X\n", c); + } + } + if (on_times && get_timer(pulse_start) > PULSETIME) { + if (led_state == 0) { + --on_times; + led_state = 1; + miconCntl_SendCmd(HDDLEDON); + } else { + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + } + pulse_start = get_timer(0); + } + if (!on_times && get_timer(pulse_start) > LONGPAUSE) { + on_times = cons_choice+1; + led_state = 0; + miconCntl_SendCmd(HDDLEDOFF); + pulse_start = get_timer(0); + } + } + if (led_state); + miconCntl_SendCmd(HDDLEDOFF); +} + +int avr_input(void) +{ + char avr_button; + int ret; + + if (!avr_tstc()) + return 0; + + avr_button = avr_getc(); + switch (avr_button) { + case PWRP: + if (push_timeout(PWRR)) { + /* Timeout before power button release */ + boot_stop = ~boot_stop; + if (boot_stop) + miconCntl_SendCmd(PWRBLINKSTOP); + else + miconCntl_SendCmd(PWRBLINKSTRT); + /* Wait for power button release */ + while (avr_getc() != PWRR) + ; + } + else + /* Power button released */ + next_boot_choice(); + break; + case RESP: + /* Wait for Reset button release */ + while (avr_getc() != RESR) + ; + next_cons_choice(cons_choice); + break; + case AVRINIT: + return 0; + default: + perror("Unexpected code: 0x%02X\n", avr_button); + return 0; + } + if (boot_stop) + return (-3); + else + return (-2); +} + +void avr_StopBoot(void) +{ + boot_stop = ~0; + miconCntl_SendCmd(PWRBLINKSTOP); +} + +/* vim: set ts=4: */ diff -urN u-boot-86xx/board/linkstation/bootls.c u-boot-86xx-kuro_clean/board/linkstation/bootls.c --- u-boot-86xx/board/linkstation/bootls.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/bootls.c 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,304 @@ +/* + * bootls.c + * + * Boot a Linkstation kernel of type firmimg.bin + * + * U-Boot loader code for Linkstation kernel. A file of type firmimg.bin + * consists of a header, immediately followed by a compressed kernel image, + * followed by a compressed initrd image. + * + * Copyright (C) 2006 Mihai Georgian + * + * 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 + * + * Derived from: + * + * arch/ppc/common/misc-simple.c (linux-2.4.17_mvl21-sandpoint) + * Author: Matt Porter + * Derived from arch/ppc/boot/prep/misc.c + * 2001 (c) MontaVista, Software, Inc. + * + * common/cmd_bootm.c (u-boot-1.1.4) + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + */ + +#include +#include + +#include "firminfo.h" + +#define _ALIGN(addr,size) (((addr)+size-1)&(~(size-1))) + +struct bi_record { + unsigned long tag; /* tag ID */ + unsigned long size; /* size of record (in bytes) */ + unsigned long data[0]; /* data */ +}; + +#define BI_FIRST 0x1010 /* first record - marker */ +#define BI_LAST 0x1011 /* last record - marker */ + +extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); +extern int gunzip(void *, int, unsigned char *, int *); + +/* + * output BYTE data + */ +static inline void outb(volatile unsigned char *addr, int val) +{ + asm volatile("eieio"); + asm volatile("stb%U0%X0 %1,%0; sync; isync" : "=m" (*addr) : "r" (val)); +} + +unsigned long checksum_check(unsigned char* addr, unsigned long size) +{ + long *laddr = (long *)addr; + unsigned long sum = 0,remain = 0; + int i; + while(size>=4) { + sum += *laddr; + laddr++; + size -= 4; + } + addr = (unsigned char*)laddr; + for(i=0;i<4;++i) { + remain = remain << 8; + if(size>i) remain += *addr; + addr++; + } + sum += remain; + return sum; +} + +void do_boot_lskernel (cmd_tbl_t *cmdtp, + int flag, + int argc, + char *argv[], + unsigned long load_addr, + unsigned long *len_ptr, + int verify) +{ + DECLARE_GLOBAL_DATA_PTR; + + char *zimage_start; + int zimage_size; + unsigned long initrd_start; + unsigned long initrd_end; + unsigned long sp; + unsigned long cmd_start; + unsigned long cmd_end; + char *cmdline; + char *s; + bd_t *kbd; + void (*kernel)(bd_t *, ulong, ulong, ulong, ulong); + unsigned long iflag; + struct firminfo *info = (struct firminfo *)load_addr; + struct bi_record *rec; + + int i; + char *flashstr="FLASH"; + + for (i=0; i <= 4; i++) + if (info->subver[i] != flashstr[i]) { + puts ("Not a Linkstation kernel\n"); + return; + } + + printf("\n******* Product Information *******\n"); + printf("----------------------------------\n"); + + printf("Product Name: %s\n", info->firmname); + printf(" VER: %d.%02d\n", info->ver_major, info->ver_minor); + printf(" Date: %d/%d/%d %d:%d:%d\n", + info->year+1900, info->mon, info->day, + info->hour,info->min,info->sec); + printf("----------------------------------\n"); + + if (verify) { + printf("Verifying checksum... "); + if (checksum_check((unsigned char*)info, info->size) != 0) { + printf("Failed!: checksum %08X, expecting 0\n", + checksum_check((unsigned char*)info, info->size)); + return; /* Returns on error */ + } else + printf("OK\n"); + } + + zimage_start = (char*)info + info->kernel_offset; + zimage_size = (int)info->kernel_size; + iflag = disable_interrupts(); + puts("Uncompressing kernel..."); + if (gunzip(0, 0x400000, zimage_start, &zimage_size) != 0) { + puts ("Failed! MUST reset board to recover\n"); + do_reset (cmdtp, flag, argc, argv); + } else + puts("done.\n"); + + /* + * Allocate space for command line and board info - the + * address should be as high as possible within the reach of + * the kernel (see CFG_BOOTMAPSZ settings), but in unused + * memory, which means far enough below the current stack + * pointer. + */ + + asm( "mr %0,1": "=r"(sp) : ); + debug ("## Current stack ends at 0x%08lX ", sp); + sp -= 2048; /* just to be sure */ + if (sp > CFG_BOOTMAPSZ) + sp = CFG_BOOTMAPSZ; + sp &= ~0xF; + debug ("=> set upper limit to 0x%08lX\n", sp); + + cmdline = (char *)((sp - CFG_BARGSIZE) & ~0xF); + if ((s = getenv("bootargs")) == NULL) + s = "root=/dev/hda1"; + strcpy (cmdline, s); + cmd_start = (ulong)&cmdline[0]; + cmd_end = cmd_start + strlen(cmdline); + debug ("## cmdline at 0x%08lX ... 0x%08lX\n", cmd_start, cmd_end); + + kbd = (bd_t *)(((ulong)cmdline - sizeof(bd_t)) & ~0xF); + *kbd = *(gd->bd); + if ((s = getenv ("clocks_in_mhz")) != NULL) { + /* convert all clock information to MHz */ + kbd->bi_intfreq /= 1000000L; + kbd->bi_busfreq /= 1000000L; + } + + kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))0x4; + + if (info->initrd_size > 0) { + initrd_start = (unsigned long)((char*)info + info->initrd_offset); + initrd_end = initrd_start + info->initrd_size; + if(initrd_start > 0xffc00000 && initrd_end < 0xffefffff) { + unsigned long nsp; + unsigned long data; + + data = initrd_start; + /* + * the inital ramdisk does not need to be within + * CFG_BOOTMAPSZ as it is not accessed until after + * the mm system is initialised. + * + * do the stack bottom calculation again and see if + * the initrd will fit just below the monitor stack + * bottom without overwriting the area allocated + * above for command line args and board info. + */ + asm( "mr %0,1": "=r"(nsp) : ); + nsp -= 2048; /* just to be sure */ + nsp &= ~0xF; + nsp -= info->initrd_size; + nsp &= ~(4096 - 1); /* align on page */ + initrd_start = nsp; + initrd_end = initrd_start + info->initrd_size; + printf ("Loading Ramdisk at 0x%08lX, end 0x%08lX ... ", + initrd_start, initrd_end); + memmove ((void *)initrd_start, (void *)data, info->initrd_size); + puts ("OK\n"); + } + } else { + initrd_start = 0; + initrd_end = 0; + } + + /* + * The kernel looks for this structure even if + * the information in it is replaced by the + * Linkstation kernel + */ + rec = (struct bi_record *)_ALIGN((unsigned long)zimage_size + + (1 << 20) - 1,(1 << 20)); + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + +#if defined(CONFIG_HLAN) || defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) + // kernel load done. + outb(0x80004500, 0x49); // send signal + outb(0x80004500, 0x49); // send signal + outb(0x80004500, 0x49); // send signal + outb(0x80004500, 0x49); // send signal +#endif +#if defined(CONFIG_HGLAN) + // full speed + udelay(10000); /* 10 msec */ + outb(0x80004500, 0x5D); // send signal + outb(0x80004500, 0x5D); // send signal + outb(0x80004500, 0x5D); // send signal + outb(0x80004500, 0x5D); // send signal +#endif +#if defined(CONFIG_HTGL) + // LINK/ACT led controll + outb(0x80004500, 0x61); // a + outb(0x80004500, 0x61); // a + outb(0x80004500, 0x39); // 9 + outb(0x80004500, 0x31); // 1 + outb(0x80004500, 0x39); // 9 + outb(0x80004500, 0x30); // 0 + outb(0x80004500, 0x92); // 1000Mbps down + outb(0x80004500, 0x92); // 1000Mbps down + + udelay(10000); /* 10 msec */ + outb(0x80004500, 0x61); // a + outb(0x80004500, 0x61); // a + outb(0x80004500, 0x39); // 9 + outb(0x80004500, 0x30); // 0 + outb(0x80004500, 0x39); // 9 + outb(0x80004500, 0x30); // 0 + outb(0x80004500, 0x90); // 100Mbps down + outb(0x80004500, 0x90); // 100Mbps down + + udelay(10000); /* 10 msec */ + outb(0x80004500, 0x61); // a + outb(0x80004500, 0x61); // a + outb(0x80004500, 0x38); // 8 + outb(0x80004500, 0x46); // F + outb(0x80004500, 0x39); // 9 + outb(0x80004500, 0x30); // 0 + outb(0x80004500, 0x8E); // 10Mbps down + outb(0x80004500, 0x8E); // 10Mbps down + + udelay(10000); /* 10 msec */ + outb(0x80004500, 0x5F); // _ + outb(0x80004500, 0x5F); // _ +#endif + +/* + * This is what the original boot loader sends + * just before jumping to the kernel start + */ + outb(0xFF000001, 0xFF); + + puts("Booting the kernel\n"); + + /* + * Linux Kernel Parameters: + * r3: ptr to board info data + * r4: initrd_start or 0 if no initrd + * r5: initrd_end - unused if r4 is 0 + * r6: Start of command line string + * r7: End of command line string + */ + (*kernel)((bd_t *)0xFF000001, initrd_start, initrd_end, cmd_start, cmd_end); +} + +/* vim: set ts=4: */ diff -urN u-boot-86xx/board/linkstation/config.mk u-boot-86xx-kuro_clean/board/linkstation/config.mk --- u-boot-86xx/board/linkstation/config.mk 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/config.mk 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,50 @@ +# +# (C) Copyright 2001-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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 +# + +# LinkStation/LinkStation-HG: +# +# Valid values for TEXT_BASE are: +# +# Standard configuration - all models +# 0xFFF00000 boot from flash +# +# Test configuration (boot from RAM using uloader.o) +# LinkStation HD-HLAN and KuroBox Standard +# 0x03F00000 boot from RAM +# LinkStation HD-HGLAN and KuroBox HG +# 0x07F00000 boot from RAM +# + +sinclude $(TOPDIR)/board/$(BOARDDIR)/config.tmp + +ifndef TEXT_BASE +# For flash image - all models +TEXT_BASE = 0xFFF00000 +# For RAM image +# HLAN and LAN +#TEXT_BASE = 0x03F00000 +# HGLAN and HGTL +#TEXT_BASE = 0x07F00000 +endif + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) diff -urN u-boot-86xx/board/linkstation/early_init.S u-boot-86xx-kuro_clean/board/linkstation/early_init.S --- u-boot-86xx/board/linkstation/early_init.S 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/early_init.S 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,432 @@ +/* + * board/linkstation/early_init.S + * + * Begin at some arbitrary location in RAM or Flash + * Initialize core registers + * Configure memory controller (Not executing from RAM) + * Initialize UARTs + * Simple RAM test (currently suspended) + * + * Copyright (C) 2006 Mihai Georgian + * + * 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 + * + * Modified for U-Boot from arch/ppc/boot/linkstation/head.S from + * the GPL code for the Buffalo Terastation, derived in its turn from: + * + * arch/ppc/boot/sandpoint/head.S + * + * Initial board bringup code for Motorola SPS Sandpoint test platform + * + * Author: Mark A. Greer + * mgreer@mvista.com + * Derived from arch/ppc/boot/pcore/head.S (mporter@mvista.com) + * + * Copyright 2001 MontaVista Software Inc. + */ + +#include +#include +#include +#include +#include + +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) +#define RAM_SIZE 0x04000000 +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) +#define RAM_SIZE 0x08000000 +#endif + +#define UART1 0x80004500 +#define UART1_IER 0x80004501 +#define UART1_FCR 0x80004502 +#define UART1_LCR 0x80004503 +#define UART1_DCR 0x80004511 +#define UART2 0x80004600 +#define UART2_IER 0x80004601 +#define UART2_FCR 0x80004602 +#define UART2_LCR 0x80004603 +#define UART2_DCR 0x80004611 + +#define WM32(address,data) \ + lis r3, address@h; \ + ori r3, r3, address@l; \ + lis r4, data@h; \ + ori r4, r4, data@l; \ + stw r4, 0x0000(r3); \ + sync; \ + isync; + +#define WM16(address,data) \ + lis r3, address@h; \ + ori r3, r3, address@l; \ + li r4, data; \ + sth r4, 0x0000(r3); \ + sync; \ + isync; + +#define WM8(address,data) \ + lis r3, address@h; \ + ori r3, r3, address@l; \ + li r4, data; \ + stb r4, 0(r3); \ + sync; \ + isync; + + .text + + .globl early_init_f +early_init_f: +/* + * Configure core registers + */ + + /* Establish default MSR value, exception prefix 0xFFF */ + li r3,MSR_IP|MSR_FP + mtmsr r3 + + /* Clear BATS */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT0L,r8 + mtspr DBAT1U,r8 + mtspr DBAT1L,r8 + mtspr DBAT2U,r8 + mtspr DBAT2L,r8 + mtspr DBAT3U,r8 + mtspr DBAT3L,r8 + mtspr IBAT0U,r8 + mtspr IBAT0L,r8 + mtspr IBAT1U,r8 + mtspr IBAT1L,r8 + mtspr IBAT2U,r8 + mtspr IBAT2L,r8 + mtspr IBAT3U,r8 + mtspr IBAT3L,r8 + isync + sync + sync + + /* Set segment registers */ + lis r8, 0x0000 + isync + mtsr SR0,r8 + mtsr SR1,r8 + mtsr SR2,r8 + mtsr SR3,r8 + mtsr SR4,r8 + mtsr SR5,r8 + mtsr SR6,r8 + mtsr SR7,r8 + mtsr SR8,r8 + mtsr SR9,r8 + mtsr SR10,r8 + mtsr SR11,r8 + mtsr SR12,r8 + mtsr SR13,r8 + mtsr SR14,r8 + mtsr SR15,r8 + isync + sync + sync + + /* Disable L1 icache/dcache */ + li r4,0x0000 + isync + mtspr HID0,r4 + sync + isync + + /* Flash Invalidate L1 icache/dcache */ + + ori r4,r4,0x8000 + ori r8,r4,0x0800 + isync + mtspr HID0,r8 + sync + isync + + /* Older cores need to manually clear ICFI bit */ + + mtspr HID0,r4 + sync + isync + +#if !defined(CFG_RAMBOOT) +melco_config_start: + /* --- CPU Configration registor setting for LinkStation --- */ + WM32(0x80041020,0x000000a0) /* Reset EPIC */ + + /* errata for latency timer */ + WM32(0xFEC00000,0x0d000080) + WM8(0xFEE00001,0x20) + /* cash size */ + WM32(0xFEC00000,0x0c000080) + WM8(0xFEE00000,0x08) + /* PCI configuration command register */ + WM32(0xFEC00000,0x04000080) + WM16(0xFEE00000,0x0600) + /* Processor interface configuration register 1 */ + WM32(0xFEC00000,0xa8000080) + /* WM32(0xFEE00000,0xd8131400) */ + lis r3, 0xFEE00000@h + ori r3, r3, 0xFEE00000@l + + lwz r5, 0(r3) /* load PCIR1 Config */ + lis r4, 0x0 + ori r4, r4, 0x1000 + and r5, r4, r5 /* Get Bit20(RCS0) */ + + lis r4, 0xd8130400@h + ori r4, r4, 0xd8130400@l + or r4, r4, r5 /* Save (RCS0) */ + + stw r4, 0x0000(r3) + sync + isync + + /* Processor interface configuration register 2 */ + WM32(0xFEC00000,0xac000080) + WM32(0xFEE00000,0x00000004) + /* Embeded Utility Memory Block Base Address register */ + WM32(0xFEC00000,0x78000080) + WM32(0xFEE00000,0x00000080) + /* Address map B option register */ + WM32(0xFEC00000,0xe0000080) + WM8(0xFEE00000,0x20) /* DLL_RESET on */ + + /* Address map B option register */ + WM32(0xFEC00000,0xe0000080) + WM8(0xFEE00000,0xc0) + /* PCI arbiter control register */ + WM32(0xFEC00000,0x46000080) + WM16(0xFEE00002,0x00c0) + + /* Added to use the high drive strength for the memory selects & addressing */ + WM32(0xFEC00000,0x73000080) + /* WM8(0xFEE00003,0x15) */ /*0x17*/ + /* Motorola Errata refer to User's Manual Errata#19 */ + /* WM8(0xFEE00003,0xD5) */ + WM8(0xFEE00003,0x95) + + /* set miscellaneous I/O control register 1 */ + WM32(0xFEC00000,0x76000080) + WM8(0xFEE00002,0x00) /*0x02*/ + /* set miscellaneous I/O control register 2 */ + WM32(0xFEC00000,0x77000080) + WM8(0xFEE00003,0x30) /* 0x30 */ + + /* init memory controller */ + WM32(0xFEC00000,0x80000080) + WM32(0xFEE00000,0x00FFFFFF) + + WM32(0xFEC00000,0x84000080) + WM32(0xFEE00000,0xFFFFFFFF) + + WM32(0xFEC00000,0x90000080) +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) + WM32(0xFEE00000,0x3FFFFFFF) /* 64MB */ +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) + WM32(0xFEE00000,0x7FFFFFFF) /* 128MB */ +#endif + + WM32(0xFEC00000,0x94000080) + WM32(0xFEE00000,0xFFFFFFFF) + + WM32(0xFEC00000,0x88000080) + WM32(0xFEE00000,0x00030303) + /* EMSAR2 */ + WM32(0xFEC00000,0x8C000080) + WM32(0xFEE00000,0x03030303) + /* select EMSER1 */ + WM32(0xFEC00000,0x98000080) + WM32(0xFEE00000,0x00030303) + /* select EMSER2 */ + WM32(0xFEC00000,0x9C000080) + WM32(0xFEE00000,0x03030303) + + /* MMCR1 */ + WM32(0xFEC00000,0xf0000080) +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) + WM32(0xFEE00000,0x0200E005) /* bank 0 13xnx4 */ +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) + WM32(0xFEE00000,0x0200E005) /* bank 0 13xnx4 */ +#endif + /* MCCR2 */ + WM32(0xFEC00000,0xf4000080) +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) + WM32(0xFEE00000,0xe0150000) /* 100MHz Memory bus */ +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) + WM32(0xFEE00000,0x80150000) /* 133MHz Memory bus */ +#endif + /* MCCR3 */ + WM32(0xFEC00000,0xf8000080) + WM32(0xFEE00000,0x00000077) /* BSTOPRE_M =7 / REFREC=8 */ + + /* MCCR4 */ + WM32(0xFEC00000,0xfc000080) +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) + WM32(0xFEE00000,0x29233222) /* CAS latency=2, burst length=8, Ext Rom=eable */ +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) + WM32(0xFEE00000,0x29323222) /* CAS latency=3, burst length=4, Ext Rom=eable */ +#endif + + /* Output driver control register */ + WM32(0xFEC00000,0x73000080) + WM8(0xFEE00003,0x15) /* for all 40 ohm */ + /* CLK driver Control Register */ + WM32(0xFEC00000,0x74000080) + WM16(0xFEE00000,0x7078) + /* select MBEN */ + WM32(0xFEC00000,0xa0000080) + WM8(0xFEE00000, 0x01) + /* MPM */ + WM32(0xFEC00000,0xa3000080) +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) + WM8(0xFEE00003,0xF2) /* PGMAX = 242 */ +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) + WM8(0xFEE00003,0xC9) /* PGMAX = 201 */ +#endif + /* ERCR s */ + WM32(0xFEC00000,0xd0000080) /* ; select ERCR1 */ + WM32(0xFEE00000,0xffffff85) + WM32(0xFEC00000,0xd4000080) /* ; select ERCR2 */ + WM32(0xFEE00000,0xffffff05) + WM32(0xFEC00000,0xd8000080) /* ; select ERCR3 */ + WM32(0xFEE00000,0x0000f80f) + WM32(0xFEC00000,0xdc000080) /* ; select ERCR4 */ + WM32(0xFEE00000,0x0e000000) + + /* MCCR1 */ + WM32(0xFEC00000,0xf0000080) + WM32(0xFEE00000,0x0200E805) /* 11 + 3 clock wait MEMGO on */ + + /* Init UART for AVR */ + WM8(UART1_LCR,0x00) /* clear LCR */ + WM8(UART1_IER,0x00) /* disable interrupt */ + WM8(UART1_LCR,0x80) /* set LCR[DLAB] bit */ + WM8(UART1_DCR,0x01) /* set DUART mode */ +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) + WM8(UART1, 0x8B) /* set DLL(baudrate 9600bps, 100MHz) */ + WM8(UART1_IER,0x02) /* set DLM(baudrate 9600bps, 100MHz) */ +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) + WM8(UART1, 0x61) /* set DLL(baudrate 9600bps, 133MHz) */ + WM8(UART1_IER,0x03) /* set DLM(baudrate 9600bps, 133MHz) */ +#endif + WM8(UART1_LCR,0x1b) /* set 8data, 1stop, even parity */ + WM8(UART1, 0x00) /* clear MCR */ + WM8(UART1_FCR,0x07) /* clear & enable FIFO */ + + /* Init UART for CONSOLE */ + WM8(UART2_LCR,0x00) /* clear LCR */ + WM8(UART2_IER,0x00) /* disable interrupt */ + WM8(UART2_LCR,0x80) /* set LCR[DLAB] bit */ + WM8(UART1_DCR,0x01) /* set DUART mode */ +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) + WM8(UART2, 0x6C) /* set DLL(baudrate 57600bps, 100MHz) */ + WM8(UART2_IER,0x00) /* set DLM(baudrate 57600bps, 100MHz) */ +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) + WM8(UART2, 0x90) /* set DLL(baudrate 57600bps, 133MHz) */ + WM8(UART2_IER,0x00) /* set DLM(baudrate 57600bps, 133MHz) */ +#endif + WM8(UART2_LCR,0x03) /* set 8data, 1stop, non parity */ + WM8(UART2, 0x00) /* clear MCR */ + WM8(UART2_FCR,0x07) /* clear & enable FIFO */ +#endif /* !defined (CFG_RAMBOOT) + + /* PCI Command Register initialize */ + lis r3, 0x8000 + ori r3, r3, 0x0004 + lis r4, 0xFEC0 + ori r4, r4, 0x0000 + stwbrx r4, 0, r3 + sync + isync + + li r6, 0x0006 + lis r5, 0xFEE0 + ori r5, r5, 0x0000 + sthbrx r5, 0, r6 + sync + isync + +#if !defined(CFG_RAMBOOT) +check_ram: + /* Wait 1 sec for AVR become enable */ + li r3,1000 + mulli r3,r3,1000 + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,39 + li r5,40 /* 40ns if for 100 Mhz bus */ + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +#if 1 +3: +#else + /* Check RAM */ + /* set start address(0x00000000) */ +3: xor r4,r4,r4 + lis r5, RAM_SIZE@h + ori r5, r5, RAM_SIZE@l + lis r6, 0xaaaa /* mask pattern a */ + ori r6, r6, 0xaaaa + lis r7, 0x5555 /* mask pattern b */ + ori r7, r7, 0x5555 + lis r8, 0x0000 /* check step size */ + ori r8, r8, 0x0100 +check_ram_loop: + cmp 0,r4,r5 + beq check_ram_end + stw r6,0(r4) + isync + lwz r3,0(r4) + isync + cmp 0,r3,r6 + bne ram_error + stw r7,0x00fc(r4) + isync + lwz r3,0x00fc(r4) + isync + cmp 0,r3,r7 + bne ram_error + add r4,r4,r8 + b check_ram_loop +ram_error: +#if defined(CONFIG_LAN) + WM8(UART1,0x39) /* ram error */ +#elif defined(CONFIG_HGLAN) ||defined(CONFIG_HLAN) || defined(CONFIG_HTGL) + WM8(UART1,0x6F) /* ram error */ +#endif + b ram_error +check_ram_end: +#endif /* #if 1 */ +#endif /* !defined (CFG_RAMBOOT) */ + +/* The instruction cache is enabled and the data cache is disabled */ + blr diff -urN u-boot-86xx/board/linkstation/firminfo.h u-boot-86xx-kuro_clean/board/linkstation/firminfo.h --- u-boot-86xx/board/linkstation/firminfo.h 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/firminfo.h 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,27 @@ +#define FIRMNAME_MAX 31 +#define SUBVERSION_MAX 31 +#define FIRMINFO_VER 1 + +struct firminfo { + unsigned long info_ver; + unsigned long firmid; + char firmname[FIRMNAME_MAX+1]; + char subver[SUBVERSION_MAX+1]; + unsigned short ver_major; + unsigned short ver_minor; + unsigned short build; + char year; + char mon; + char day; + char hour; + char min; + char sec; + unsigned long size; + unsigned long chksum; + + unsigned long kernel_offset; + unsigned long kernel_size; + unsigned long initrd_offset; + unsigned long initrd_size; + } __attribute((aligned(4))); +// ---------------------------------------------------- diff -urN u-boot-86xx/board/linkstation/flash.c u-boot-86xx-kuro_clean/board/linkstation/flash.c --- u-boot-86xx/board/linkstation/flash.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/flash.c 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,893 @@ +/* + * flash.c + * + * Flash device interface for LinkStation + * Supports CFI flash devices using the AMD standard command set + * + * Copyright (C) 2006 Mihai Georgin + * + * 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 + * + * Based on the MTD code from the Linux kernel + * + * Based on include/melco/flashd.c (linux-2.4.17_mvl21-sandpoint) + * Copyright (C) 2001-2004 BUFFALO INC. + */ +#include +#include +#include + +#if 0 +#define DEBUG_CFI +#endif + +#undef debug +#ifdef DEBUG_CFI +#define debug(fmt,args...) printf(fmt,##args) +#else +#define debug(fmt,args...) +#endif /* DEBUG_CFI */ + +#if CFG_MAX_FLASH_BANKS > 1 +#error Only 1 flash bank supported +#endif + +#define perror(fmt,args...) printf("%s: ",__FUNCTION__);printf(fmt,##args) + +#define MAX_ERASE_REGIONS 4 + +#define P_ID_NONE 0 +#define P_ID_INTEL_EXT 1 +#define P_ID_AMD_STD 2 +#define P_ID_INTEL_STD 3 +#define P_ID_AMD_EXT 4 +#define P_ID_MITSUBISHI_STD 256 +#define P_ID_MITSUBISHI_EXT 257 +#define P_ID_RESERVED 65535 + +#define CFI_DEVICETYPE_X8 (8 / 8) +#define CFI_DEVICETYPE_X16 (16 / 8) + +#define FLASH_DATA_MASK 0xFF + +#define FUJ_MANUFACT_LS (FUJ_MANUFACT & FLASH_DATA_MASK) +#define STM_MANUFACT_LS (STM_MANUFACT & FLASH_DATA_MASK) +#define MX_MANUFACT_LS (MX_MANUFACT & FLASH_DATA_MASK) + +/* Unknown manufacturer */ +#define FLASH_MAN_UNKNOWN 0xFFFF0000 + +/* Fujitsu MBM29PL320MT which is using the same */ +/* codes as the AMD Am29LV320MT "mirror" flash */ +#define AMD_ID_MIRROR_LS (AMD_ID_MIRROR & FLASH_DATA_MASK) +#define AMD_ID_LV320T_2_LS (AMD_ID_LV320T_2 & FLASH_DATA_MASK) +#define AMD_ID_LV320T_3_LS (AMD_ID_LV320T_3 & FLASH_DATA_MASK) + +/* ST Micro M29W320DT and M29W320DB */ +#define STM_ID_29W320DT_LS (STM_ID_29W320DT & FLASH_DATA_MASK) +#define STM_ID_29W320DB_LS (STM_ID_29W320DB & FLASH_DATA_MASK) + +/* ST Micro M29DW324DT and M29DW324DB */ +#define STM_ID_29W324DT_LS (STM_ID_29W324DT & FLASH_DATA_MASK) +#define STM_ID_29W324DB_LS (STM_ID_29W324DB & FLASH_DATA_MASK) + +/* Macronix MX29LV320T */ +#define MX_ID_LV320T_LS (MX_ID_LV320T & FLASH_DATA_MASK) + +/* Basic Query Structure */ +struct cfi_ident { + __u8 qry[3]; + __u16 P_ID; + __u16 P_ADR; + __u16 A_ID; + __u16 A_ADR; + __u8 VccMin; + __u8 VccMax; + __u8 VppMin; + __u8 VppMax; + __u8 WordWriteTimeoutTyp; + __u8 BufWriteTimeoutTyp; + __u8 BlockEraseTimeoutTyp; + __u8 ChipEraseTimeoutTyp; + __u8 WordWriteTimeoutMax; + __u8 BufWriteTimeoutMax; + __u8 BlockEraseTimeoutMax; + __u8 ChipEraseTimeoutMax; + __u8 DevSize; + __u16 InterfaceDesc; + __u16 MaxBufWriteSize; + __u8 NumEraseRegions; + __u32 EraseRegionInfo[MAX_ERASE_REGIONS]; +} __attribute__((packed)); + +struct cfi_private { + __u32 base; + int device_type; + int addr_unlock1; + int addr_unlock2; + struct cfi_ident *cfiq; + int mfr; + int id[3]; /* Supports AMD MirrorBit flash */ + char *flash_name; + int wrd_wr_time; + int buf_wr_time; + int erase_time; + int (*blk_erase)(flash_info_t *info, int s_first, int s_last); + int (*blk_write)(flash_info_t *info, __u8 *buf, __u32 addr, int sz); +}; + +static inline __u8 cfi_read8(__u32 addr) +{ + return (*(volatile __u8 *)(addr)); +} + +static inline void cfi_write8(__u8 val, __u32 addr) +{ + *(volatile __u8 *)(addr) = val; + sync(); +} + +/* + * Sends a CFI command to a bank of flash for the given type. + * Returns the offset to the sent command + */ +static inline __u32 cfi_cmd(__u8 cmd, __u32 cmd_addr, __u32 base, int type) +{ + __u32 addr; + + addr = base + cmd_addr * type; + if (cmd_addr * type == 0x554) + ++addr; + + cfi_write8(cmd, addr); + + return addr - base; +} + +static inline __u8 cfi_read_query(__u32 addr) +{ + return cfi_read8(addr); +} + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; +static struct cfi_private cfis; +static struct cfi_ident cfi_idents; +static struct cfi_private *cfi; + +static int cfi_probe_chip(struct cfi_private *cfi); +static unsigned long cfi_amdstd_setup(struct cfi_private *cfi, int primary); +static void print_cfi_ident(struct cfi_ident *); +static int flash_amdstd_erase(flash_info_t *info, int s_first, int s_last); +static int flash_amdstd_wbuff(flash_info_t *info, __u8 *buf, __u32 addr,int sz); +static int flash_amdstd_wubyp(flash_info_t *info, __u8 *buf, __u32 addr,int sz); +static int flash_amdstd_write(flash_info_t *info, __u8 *buf, __u32 addr,int sz); + + + +unsigned long flash_init(void) +{ + unsigned long flash_size; + __u16 type; + + debug("%s\n", __FUNCTION__); + + cfi = &cfis; + memset(cfi, 0, sizeof(struct cfi_private)); + + cfi->base = CFG_FLASH_BASE; + + /* Identify CFI chip */ + /* Probe for X8 device first */ + cfi->device_type = CFI_DEVICETYPE_X8; + if (cfi_probe_chip(cfi)) { + /* The probe didn't like it */ + /* so probe for X16/X8 device */ + cfi->device_type = CFI_DEVICETYPE_X16; + if (cfi_probe_chip(cfi)) { + /* The probe didn't like it */ + return 0UL; + } + } + + /* Check if it is AMD standard cmd set */ + type = cfi->cfiq->P_ID; + if (type == P_ID_AMD_STD) + flash_size = cfi_amdstd_setup(cfi, 1); + else { + perror("Primary cmd set is not AMD std. Trying alternate.\n"); + flash_size = 0; + } + if (!flash_size) { + type = cfi->cfiq->A_ID; + if (type == P_ID_AMD_STD) + flash_size = cfi_amdstd_setup(cfi, 0); + else { + perror("Alternate cmd set is not AMD std.\n"); + return 0UL; + } + } + + if (flash_size && flash_size == 4*1024*1024) { + /* Flash protection ON by default */ + flash_protect(FLAG_PROTECT_SET, cfi->base, cfi->base+flash_size-1, flash_info); + + return flash_size; + } + + if (flash_size) { + perror("Unsupported flash size: %d\n", flash_size); + } else { + perror("Vendor Command Set not supported\n"); + printf("Primary: 0x%04X, Alternate: 0x%04X\n", + cfi->cfiq->P_ID, cfi->cfiq->A_ID); + } + return 0UL; +} + +void flash_print_info(flash_info_t *info) +{ + int i; + + debug("%s\n", __FUNCTION__); + + printf("Flash chip: %s\n\n", + cfi->flash_name?cfi->flash_name:"UNKNOWN"); + print_cfi_ident(cfi->cfiq); + printf("\nActual values used by U-Boot:\n"); + printf("Word write timeout: %6d ms\n", cfi->wrd_wr_time); + printf("Buffer write timeout: %6d ms\n", cfi->buf_wr_time); + printf("Sector erase timeout: %6d ms\n", cfi->erase_time); + printf("\nSize: %ld MiB in %d Sectors\n",info->size>>20,info->sector_count); + printf (" Sector Start Addresses:"); + for (i=0; isector_count; i++) { + if (!(i % 5)) + printf ("\n "); + printf (" %08lX%s", info->start[i], info->protect[i]?" (RO)" : " (RW)"); + } + printf ("\n"); +} + +int flash_erase(flash_info_t *info, int s_first, int s_last) +{ + return (*(cfi->blk_erase))(info, s_first, s_last); +} + +int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + return (*(cfi->blk_write))(info, src, addr, cnt); +} + +static int cfi_probe_chip(struct cfi_private *cfi) +{ + int ofs_factor = cfi->device_type; + __u32 base = cfi->base; + int num_erase_regions, scount; + int i; + + debug("%s\n", __FUNCTION__); + + cfi_cmd(0xF0, 0x00, base, cfi->device_type); + cfi_cmd(0x98, 0x55, base, cfi->device_type); + + if (cfi_read8(base + ofs_factor * 0x10) != 'Q' || + cfi_read8(base + ofs_factor * 0x11) != 'R' || + cfi_read8(base + ofs_factor * 0x12) != 'Y') { + debug("Not a CFI flash\n"); + /* Put the chip back into read array mode */ + cfi_cmd(0xF0, 0x00, base, cfi->device_type); + return -1; + } + + num_erase_regions = cfi_read_query(base + 0x2C * ofs_factor); + if (!num_erase_regions) { + perror("No erase regions\n"); + /* Put the chip back into read read array mode */ + cfi_cmd(0xF0, 0x00, base, cfi->device_type); + return -1; + } + if (num_erase_regions > MAX_ERASE_REGIONS) { + perror("Number of erase regions (%d) > MAX_ERASE_REGIONS (%d)\n", + num_erase_regions, MAX_ERASE_REGIONS); + /* Put the chip back into read read array mode */ + cfi_cmd(0xF0, 0x00, base, cfi->device_type); + return -1; + } + + cfi->cfiq = &cfi_idents; + memset(cfi->cfiq, 0, sizeof(struct cfi_ident)); + debug("cfi->cfiq: 0x%08X\n", cfi->cfiq); + + /* Read the CFI info structure */ + for (i=0; i < sizeof(struct cfi_ident) + num_erase_regions * 4; i++) + ((__u8 *)cfi->cfiq)[i] = cfi_read_query(base + (0x10 + i) * ofs_factor); + + /* Do any necessary byteswapping */ + cfi->cfiq->P_ID = __le16_to_cpu(cfi->cfiq->P_ID); + cfi->cfiq->P_ADR = __le16_to_cpu(cfi->cfiq->P_ADR); + cfi->cfiq->A_ID = __le16_to_cpu(cfi->cfiq->A_ID); + cfi->cfiq->A_ADR = __le16_to_cpu(cfi->cfiq->A_ADR); + cfi->cfiq->InterfaceDesc = __le16_to_cpu(cfi->cfiq->InterfaceDesc); + cfi->cfiq->MaxBufWriteSize = __le16_to_cpu(cfi->cfiq->MaxBufWriteSize); + +#if 0 + /* Dump the information therein */ + print_cfi_ident(cfi->cfiq); +#endif + + scount = 0; + for (i=0; icfiq->NumEraseRegions; i++) { + cfi->cfiq->EraseRegionInfo[i] = __le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]); + scount += (cfi->cfiq->EraseRegionInfo[i] & 0xFFFF) + 1; + debug(" Erase Region #%d: sector size 0x%4.4X bytes, %d sectors\n", + i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xFF, + (cfi->cfiq->EraseRegionInfo[i] & 0xFFFF) + 1); + } + /* Put it back into Read Mode */ + cfi_cmd(0xF0, 0, base, cfi->device_type); + + if (scount > CFG_MAX_FLASH_SECT) { + perror("Number of sectors (%d) > CFG_MAX_FLASH_SECT (%d)\n", + scount, CFG_MAX_FLASH_SECT); + return -1; + } + + debug("Found x%d device in 8-bit mode\n", cfi->device_type*8); + + return 0; +} + +static char *vendorname(__u16 vendor) +{ + switch (vendor) { + case P_ID_NONE: + return "None"; + case P_ID_INTEL_EXT: + return "Intel/Sharp Extended"; + case P_ID_AMD_STD: + return "AMD/Fujitsu Standard"; + case P_ID_INTEL_STD: + return "Intel/Sharp Standard"; + case P_ID_AMD_EXT: + return "AMD/Fujitsu Extended"; + case P_ID_MITSUBISHI_STD: + return "Mitsubishi Standard"; + case P_ID_MITSUBISHI_EXT: + return "Mitsubishi Extended"; + case P_ID_RESERVED: + return "Not Allowed / Reserved for Future Use"; + default: + return "Unknown"; + } +} + +static void print_cfi_ident(struct cfi_ident *cfip) +{ + printf("CFI Query Results:\n"); + printf("Primary Vendor Command Set: 0x%4.4X (%s)\n", + cfip->P_ID, vendorname(cfip->P_ID)); + if (cfip->P_ADR) + printf("Primary Algorithm Table at 0x%4.4X\n", cfip->P_ADR); + else + printf("No Primary Algorithm Table\n"); + + printf("Alternate Vendor Command Set: 0x%4.4X (%s)\n", + cfip->A_ID, vendorname(cfip->A_ID)); + if (cfip->A_ADR) + printf("Alternate Algorithm Table at 0x%4.4X\n", cfip->A_ADR); + else + printf("No Alternate Algorithm Table\n"); + + printf("Vcc Min.: %d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xF); + printf("Vcc Max.: %d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xF); + if (cfip->VppMin) { + printf("Vpp Min.: %d.%d V\n", cfip->VppMin >> 4, cfip->VppMin & 0xF); + printf("Vpp Max.: %d.%d V\n", cfip->VppMax >> 4, cfip->VppMax & 0xF); + } + else + printf("No Vpp line\n"); + + printf("Typical byte/word write timeout: %d us\n", + 1<WordWriteTimeoutTyp); + printf("Maximum byte/word write timeout: %d us\n", + (1<WordWriteTimeoutMax) * (1<WordWriteTimeoutTyp)); + + if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { + printf("Typical full buffer write timeout: %d us\n", + 1<BufWriteTimeoutTyp); + printf("Maximum full buffer write timeout: %d us\n", + (1<BufWriteTimeoutMax) * (1<BufWriteTimeoutTyp)); + } + else + printf("Full buffer write not supported\n"); + + printf("Typical block erase timeout: %d ms\n", + 1<BlockEraseTimeoutTyp); + printf("Maximum block erase timeout: %d ms\n", + (1<BlockEraseTimeoutMax) * (1<BlockEraseTimeoutTyp)); + if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) { + printf("Typical chip erase timeout: %d ms\n", + 1<ChipEraseTimeoutTyp); + printf("Maximum chip erase timeout: %d ms\n", + (1<ChipEraseTimeoutMax) * (1<ChipEraseTimeoutTyp)); + } + else + printf("Chip erase not supported\n"); + + printf("Device size: 0x%X bytes (%d MiB)\n", + 1 << cfip->DevSize, 1 << (cfip->DevSize - 20)); + printf("Flash Device Interface description: 0x%4.4X\n",cfip->InterfaceDesc); + switch(cfip->InterfaceDesc) { + case 0: + printf(" - x8-only asynchronous interface\n"); + break; + case 1: + printf(" - x16-only asynchronous interface\n"); + break; + case 2: + printf(" - x8 / x16 via BYTE# with asynchronous interface\n"); + break; + case 3: + printf(" - x32-only asynchronous interface\n"); + break; + case 65535: + printf(" - Not Allowed / Reserved\n"); + break; + default: + printf(" - Unknown\n"); + break; + } + printf("Max. bytes in buffer write: %d\n", 1 << cfip->MaxBufWriteSize); + printf("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions); +} + +static unsigned long cfi_amdstd_setup(struct cfi_private *cfi, int primary) +{ + flash_info_t *info = &flash_info[0]; + __u32 base = cfi->base; + int ofs_factor = cfi->device_type; + __u32 addr_et = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; + __u8 major, minor, bootloc; + __u32 offset, ernum, ersize; + int i, j; + + /* Put the chip into read array mode */ + cfi_cmd(0xF0, 0x00, base, cfi->device_type); + /* Autoselect */ + cfi_cmd(0xAA, 0x555, base, cfi->device_type); + cfi_cmd(0x55, 0x2AA, base, cfi->device_type); + cfi_cmd(0x90, 0x555, base, cfi->device_type); + /* Read manufacturer and device id */ + cfi->mfr = cfi_read_query(base + 0x00 * ofs_factor); + if ((cfi->id[0] = cfi_read_query(base + 0x01 * ofs_factor)) == 0x7E) { + cfi->id[1] = cfi_read_query(base + 0x0E * ofs_factor); + cfi->id[2] = cfi_read_query(base + 0x0F * ofs_factor); + } + /* Put the chip into read array mode */ + cfi_cmd(0xF0, 0x00, base, cfi->device_type); + + /* Put the chip into read query mode */ + cfi_cmd(0x98, 0x55, base, cfi->device_type); + /* Find the boot block location and swap the erase regions as necessary */ + major = cfi_read_query(base + (addr_et + 3) * ofs_factor); + minor = cfi_read_query(base + (addr_et + 4) * ofs_factor); + debug(" Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n", + major, minor, addr_et); + + if (((major << 8) | minor) < 0x3131) { + /* CFI version 1.0 => don't trust bootloc */ + if (cfi->id[0] & 0x80) { + printf("Device ID is 0x%02X. Assuming broken CFI table.\n", + cfi->id[0]); + bootloc = 3; /* top boot */ + } else + bootloc = 2; /* bottom boot */ + } else + bootloc = cfi_read_query(base + (addr_et + 0xF) * ofs_factor); + + if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { + debug("Top boot block. Swapping erase regions.\n"); + for (i=0; icfiq->NumEraseRegions / 2; i++) { + int j = (cfi->cfiq->NumEraseRegions-1)-i; + __u32 swap; + + swap = cfi->cfiq->EraseRegionInfo[i]; + cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; + cfi->cfiq->EraseRegionInfo[j] = swap; + } + } + + /* Put the chip into read array mode */ + cfi_cmd(0xF0, 0x00, base, cfi->device_type); + + switch (cfi->device_type) { + case CFI_DEVICETYPE_X8: + /* X8 chip */ + cfi->addr_unlock1 = 0x555; + cfi->addr_unlock2 = 0x2AA; + break; + case CFI_DEVICETYPE_X16: + /* X16 chip in X8 mode */ + cfi->addr_unlock1 = 0xAAA; + cfi->addr_unlock2 = 0x555; + break; + default: + perror("Unsupported device type %d\n", cfi->device_type); + return 0UL; + } + + cfi->wrd_wr_time = 1 << cfi->cfiq->WordWriteTimeoutTyp; + cfi->wrd_wr_time *= 1 << cfi->cfiq->WordWriteTimeoutMax; + /* Word write time is in us, convert to ms */ + cfi->wrd_wr_time = cfi->wrd_wr_time / 1000 + 1; + if (cfi->wrd_wr_time == 1) + /* Account for the timer resolution which is 1 ms */ + cfi->wrd_wr_time = 2; + cfi->buf_wr_time = 1 << cfi->cfiq->BufWriteTimeoutTyp; + cfi->buf_wr_time *= 1 << cfi->cfiq->BufWriteTimeoutMax; + /* Buffer write time is in us, convert to ms */ + cfi->buf_wr_time = cfi->buf_wr_time / 1000 + 1; + if (cfi->buf_wr_time == 1) + /* Account for the timer resolution which is 1 ms */ + cfi->buf_wr_time = 2; + cfi->erase_time = 1 << cfi->cfiq->BlockEraseTimeoutTyp; + cfi->erase_time *= 1 << cfi->cfiq->BlockEraseTimeoutMax; + + info->size = (1 << cfi->cfiq->DevSize); + + info->sector_count = 0; + offset = CFG_FLASH_BASE; + for (i=0; i < cfi->cfiq->NumEraseRegions; i++) { + ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xFF); + ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xFFFF) + 1; + + for (j=0; j < ernum; j++) { + info->start[info->sector_count + j] = offset; + offset += ersize; + } + + info->sector_count += ernum; + } + + switch (cfi->mfr) { + case FUJ_MANUFACT_LS: + info->flash_id = FLASH_MAN_FUJ; + switch (cfi->id[0]) { + case AMD_ID_MIRROR_LS: + if (cfi->id[1] == AMD_ID_LV320T_2_LS && + cfi->id[2] == AMD_ID_LV320T_3_LS) { + info->flash_id += FLASH_AMLV320T; + cfi->blk_write = flash_amdstd_wbuff; + cfi->flash_name = "FUJITSU MBM29PL32TM"; + } else + info->flash_id += FLASH_UNKNOWN; + break; + default: + info->flash_id += FLASH_UNKNOWN; + break; + } + break; + case STM_MANUFACT_LS: + info->flash_id = FLASH_MAN_STM; + switch (cfi->id[0]) { + case STM_ID_29W320DT_LS: + info->flash_id += FLASH_STMW320DT; + cfi->blk_write = flash_amdstd_wubyp; + cfi->flash_name = "STMICRO M29W320DT"; + break; + case STM_ID_29W320DB_LS: + info->flash_id += FLASH_STMW320DB; + cfi->blk_write = flash_amdstd_wubyp; + cfi->flash_name = "STMICRO M29W320DB"; + break; + case STM_ID_29W324DT_LS: + info->flash_id += FLASH_STMW324DT; + cfi->blk_write = flash_amdstd_wubyp; + cfi->flash_name = "STMICRO M29W324DT"; + break; + case STM_ID_29W324DB_LS: + info->flash_id += FLASH_STMW324DB; + cfi->blk_write = flash_amdstd_wubyp; + cfi->flash_name = "STMICRO M29W324DB"; + break; + default: + info->flash_id += FLASH_UNKNOWN; + break; + } + break; + case MX_MANUFACT_LS: + info->flash_id = FLASH_MAN_MX; + switch (cfi->id[0]) { + case MX_ID_LV320T_LS: + info->flash_id += FLASH_MXLV320T; + cfi->blk_write = flash_amdstd_write; + cfi->flash_name = "MXIC MX29LV320T"; + break; + default: + info->flash_id += FLASH_UNKNOWN; + break; + } + break; + default: + info->flash_id = FLASH_AMD_COMP; + break; + } + + if ((info->flash_id & FLASH_TYPEMASK) == FLASH_UNKNOWN) { + /* Unknown but supported CFI flash */ + cfi->flash_name = NULL; + if (cfi->cfiq->MaxBufWriteSize) + cfi->blk_write = flash_amdstd_wbuff; + else + cfi->blk_write = flash_amdstd_write; + } + + cfi->blk_erase = flash_amdstd_erase; + + return info->size; +} + +#define BIT(x) (1<base; + __u8 *faddr; + long i; + + debug("%s\n", __FUNCTION__); + + faddr = (__u8 *)addr; + for(i=0; i < sz; i++) { + if(faddr[i] != buf[i]) { + printf("Flash Write verify fail at %08x. ", &faddr[i]); + printf("Expecting: %02X, Actual: %02X\n", faddr[i], buf[i]); + printf("Retrying..."); + cfi_cmd(0xAA, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x55, cfi->addr_unlock2, base, CFI_DEVICETYPE_X8); + cfi_cmd(0xA0, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_write8(buf[i], (__u32)&faddr[i]); + if (flash_amdstd_state((__u32)&faddr[i], buf[i], cfi->wrd_wr_time)) { + printf("failed again\n"); + cfi_cmd(0xF0, 0, base, CFI_DEVICETYPE_X8); + return 1; + } else + printf("suceeded\n"); + } + } + return 0; +} + +/* + * Erase flash sectors + */ +static int flash_amdstd_erase(flash_info_t *info, int s_first, int s_last) +{ + int prot, sect, nsect, flag; + __u32 l_sect; + __u32 base = cfi->base; + + debug("%s\n", __FUNCTION__); + + if (!info->size) { + printf ("Flash erase: Can't erase unsupported flash\n"); + return 1; + } + + if (s_first < 0 || s_first > s_last || + s_first > (info->sector_count - 1) || + s_last > (info->sector_count - 1)) { + printf ("Flash erase: no sectors to erase\n"); + return 1; + } + + printf("\nFlash erase: first = %d @ 0x%08lx\n", + s_first, info->start[s_first]); + printf(" last = %d @ 0x%08lx\n", s_last, info->start[s_last]); + + nsect = s_last - s_first + 1; + for (prot = 0, sect=s_first; sect<=s_last; ++sect) + if (info->protect[sect]) + prot++; + if (prot) { + if (prot == nsect) { + printf("Warning: All requested sectors are protected!\n"); + printf(" No sectors to erase\n"); + return 1; + } + else + printf("Warning: %d protected sectors will not be erased!\n", prot); + } + cfi_cmd(0xF0, 0x00, base, CFI_DEVICETYPE_X8); + udelay(1000); + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + cfi_cmd(0xAA, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x55, cfi->addr_unlock2, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x80, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_cmd(0xAA, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x55, cfi->addr_unlock2, base, CFI_DEVICETYPE_X8); + for (sect = s_first; sect <= s_last; sect++) + if (!info->protect[sect]) { + l_sect = info->start[sect]; + cfi_write8(0x30, l_sect); + } + /* Erase begins 50us after the last sector address */ + udelay(50); + + /* All erase commands sent, enable interrupts */ + if (flag) + enable_interrupts(); + + if (flash_amdstd_state(l_sect, 0xff, cfi->erase_time * nsect)) { + printf("Flash erase: Timeout\n"); + cfi_cmd(0xF0, 0x00, base, CFI_DEVICETYPE_X8); + return 1; + } + printf("Flash erase: Done\n"); + return 0; +} + +/* + * Write to flash using Write Buffer programming + */ +static int flash_amdstd_wbuff(flash_info_t *info, __u8 *buf, __u32 addr, int sz) +{ + __u32 base = cfi->base; + __u32 wbufsz; + __u32 size, wsize, waddr, saddr; + __u8 *wbuf; + int i; + + debug("%s\n", __FUNCTION__); + + size = sz; + wbuf = buf; + wbufsz = 1 << cfi->cfiq->MaxBufWriteSize; + + waddr = (addr + wbufsz - 1) & ~(wbufsz - 1); + if (waddr > addr) + wsize = waddr-addr; + else + wsize = wbufsz; + if (wsize > size) + wsize = size; + waddr = addr; + + while (size > 0) { + for (i = 0; i < info->sector_count; i++) + if (waddr < info->start[i]) + break; + saddr = info->start[i-1]; + + cfi_cmd(0xAA, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x55, cfi->addr_unlock2, base, CFI_DEVICETYPE_X8); + cfi_write8(0x25, saddr); + cfi_write8(wsize-1, saddr); + for (i = 0; i < wsize; i++) + cfi_write8(*wbuf++, waddr++); + cfi_write8(0x29, saddr); + + if (flash_amdstd_state(waddr-1, *(wbuf-1), cfi->buf_wr_time)) { + printf("Flash write buffer: Timeout\n"); + cfi_cmd(0xF0, 0x00, base, CFI_DEVICETYPE_X8); + return 1; + } + + size -= wsize; + if ((wsize = wbufsz) > size) + wsize = size; + } + + return flash_amdstd_vrfy(info, buf, addr, sz); +} + +/* + * Write to flash using Unlock Bypass command sequence + */ +static int flash_amdstd_wubyp(flash_info_t *info, __u8 *buf, __u32 addr, int sz) +{ + __u32 base = cfi->base; + __u32 waddr; + long i; + + debug("%s\n", __FUNCTION__); + + waddr = addr; + + cfi_cmd(0xAA, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x55, cfi->addr_unlock2, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x20, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + + for(i=0; i < sz; i++) { + cfi_write8(0xA0, waddr); + cfi_write8(buf[i], waddr); + if (flash_amdstd_state(waddr, buf[i], cfi->wrd_wr_time)) { + printf("Flash unlock bypass write: Timeout\n"); + cfi_cmd(0x90, 0, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x00, 0, base, CFI_DEVICETYPE_X8); + cfi_cmd(0xF0, 0, base, CFI_DEVICETYPE_X8); + return 1; + } + waddr++; + } + cfi_cmd(0x90, 0, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x00, 0, base, CFI_DEVICETYPE_X8); + cfi_cmd(0xF0, 0, base, CFI_DEVICETYPE_X8); + + return flash_amdstd_vrfy(info, buf, addr, sz); +} + +/* + * Write to flash using Word/Byte Program command sequence + */ +static int flash_amdstd_write(flash_info_t *info, __u8 *buf, __u32 addr, int sz) +{ + __u32 base = cfi->base; + __u32 waddr; + long i; + + debug("%s\n", __FUNCTION__); + + waddr = addr; + + cfi_cmd(0xF0, 0, base, CFI_DEVICETYPE_X8); + for (i = 0; i < sz; i++) { + cfi_cmd(0xAA, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_cmd(0x55, cfi->addr_unlock2, base, CFI_DEVICETYPE_X8); + cfi_cmd(0xA0, cfi->addr_unlock1, base, CFI_DEVICETYPE_X8); + cfi_write8(buf[i], waddr); + if (flash_amdstd_state(waddr, buf[i], cfi->wrd_wr_time)) { + printf("Flash write: Timeout\n"); + cfi_cmd(0xF0, 0, base, CFI_DEVICETYPE_X8); + return 1; + } + waddr++; + } + cfi_cmd(0xF0, 0, base, CFI_DEVICETYPE_X8); + + return flash_amdstd_vrfy(info, buf, addr, sz); +} + +/* vim: set ts=4: */ diff -urN u-boot-86xx/board/linkstation/hwctl.c u-boot-86xx-kuro_clean/board/linkstation/hwctl.c --- u-boot-86xx/board/linkstation/hwctl.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/hwctl.c 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,258 @@ +/* + * hwctl.c + * + * LinkStation HW Control Driver + * + * Copyright (C) 2001-2004 BUFFALO INC. + * + * This software may be used and distributed according to the terms of + * the GNU General Public License (GPL), incorporated herein by reference. + * Drivers based on or derived from this code fall under the GPL and must + * retain the authorship, copyright and license notice. This file is not + * a complete program and may only be used when the entire operating + * system is licensed under the GPL. + * + */ + +#include +#include +#include + +#define mdelay(n) udelay((n)*1000) + +#define AVR_PORT CFG_NS16550_COM2 +extern void udelay(unsigned long usec); + + +// output BYTE data +static inline void out_b(volatile unsigned char *addr, int val) +{ + __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val)); +} + +#if 0 +// PWR,DISK_FULL/STATUS,DIAG LED controll +void blink_led(unsigned char state) +{ +#ifdef CONFIG_HTGL + switch (state) + { + case FLASH_CLEAR_START: + case FLASH_UPDATE_START: + out_b(AVR_PORT, 0x61); + out_b(AVR_PORT, 0x61); + out_b(AVR_PORT, 0x38); + out_b(AVR_PORT, 0x30); + out_b(AVR_PORT, 0x34); + out_b(AVR_PORT, 0x31); + mdelay(10); + out_b(AVR_PORT, 0x61); + out_b(AVR_PORT, 0x61); + out_b(AVR_PORT, 0x38); + out_b(AVR_PORT, 0x31); + out_b(AVR_PORT, 0x34); + out_b(AVR_PORT, 0x31); + mdelay(10); + out_b(AVR_PORT, 0x71); + out_b(AVR_PORT, 0x71); +// out_b(AVR_PORT, 0x71); +// out_b(AVR_PORT, 0x71); + mdelay(10); + out_b(AVR_PORT, 0x73); + out_b(AVR_PORT, 0x73); +// out_b(AVR_PORT, 0x73); +// out_b(AVR_PORT, 0x73); + mdelay(10); + break; + case FLASH_CLEAR_END: + case FLASH_UPDATE_END: + out_b(AVR_PORT, 0x70); + out_b(AVR_PORT, 0x70); +// out_b(AVR_PORT, 0x70); +// out_b(AVR_PORT, 0x70); + mdelay(10); + out_b(AVR_PORT, 0x72); + out_b(AVR_PORT, 0x72); +// out_b(AVR_PORT, 0x72); +// out_b(AVR_PORT, 0x72); + mdelay(10); + break; + case RAID_RESYNC_START: + break; + case RAID_RESYNC_END: + break; + default: + out_b(AVR_PORT, state); + out_b(AVR_PORT, state); + out_b(AVR_PORT, state); + out_b(AVR_PORT, state); + break; + } +#else + out_b(AVR_PORT, state); + out_b(AVR_PORT, state); + out_b(AVR_PORT, state); + out_b(AVR_PORT, state); +#endif + +} +#endif + +// 2005.5.10 BUFFALO add +//-------------------------------------------------------------- +static inline void miconCntl_SendUart(unsigned char dat) +{ + out_b((char *)AVR_PORT, dat); + udelay(1000); +} + +//-------------------------------------------------------------- +void miconCntl_SendCmd(unsigned char dat) +{ + int i; + + for (i=0; i<4; i++){ + miconCntl_SendUart(dat); + } +} + +//-------------------------------------------------------------- +void miconCntl_FanLow(void) +{ + debug("%s\n",__FUNCTION__); +#ifdef CONFIG_HTGL + miconCntl_SendCmd(0x5C); +#endif +} +//-------------------------------------------------------------- +void miconCntl_FanHigh(void) +{ + debug("%s\n",__FUNCTION__); +#ifdef CONFIG_HTGL + miconCntl_SendCmd(0x5D); +#endif +} + +//-------------------------------------------------------------- +//1000Mbps +void miconCntl_Eth1000M(int up) +{ + debug("%s (%d)\n",__FUNCTION__,up); +#ifdef CONFIG_HTGL + if (up){ + miconCntl_SendCmd(0x93); + }else{ + miconCntl_SendCmd(0x92); + } +#else + if (up){ + miconCntl_SendCmd(0x5D); + }else{ + miconCntl_SendCmd(0x5C); + } +#endif +} +//-------------------------------------------------------------- +//100Mbps +void miconCntl_Eth100M(int up) +{ + debug("%s (%d)\n",__FUNCTION__,up); +#ifdef CONFIG_HTGL + if (up){ + miconCntl_SendCmd(0x91); + }else{ + miconCntl_SendCmd(0x90); + } +#else + if (up){ + miconCntl_SendCmd(0x5C); + } +#endif +} +//-------------------------------------------------------------- +//10Mbps +void miconCntl_Eth10M(int up) +{ + debug("%s (%d)\n",__FUNCTION__,up); +#ifdef CONFIG_HTGL + if (up){ + miconCntl_SendCmd(0x8F); + }else{ + miconCntl_SendCmd(0x8E); + } +#else + if (up){ + miconCntl_SendCmd(0x5C); + } +#endif +} +//-------------------------------------------------------------- +//�������� +void miconCntl_5f(void) +{ + debug("%s\n",__FUNCTION__); + miconCntl_SendCmd(0x5F); + mdelay(100); +} + +//-------------------------------------------------------------- +// "reboot start" signal +void miconCntl_Reboot(void) +{ + debug("%s\n",__FUNCTION__); + miconCntl_SendCmd(0x43); +} +#if 0 +//-------------------------------------------------------------- +// Raid recovery start +void miconCntl_RadiRecovery(void) +{ + debug("%s\n",__FUNCTION__); +#ifdef CONFIG_HTGL + miconCntl_SendUart(0x61); // a + miconCntl_SendUart(0x61); // a + miconCntl_SendUart(0x38); // 8 + miconCntl_SendUart(0x30); // 0 + miconCntl_SendUart(0x34); // 4 + miconCntl_SendUart(0x31); // 1 + miconCntl_SendCmd(0x71); // q +#endif +} +//-------------------------------------------------------------- +// Raid recovery finish +void miconCntl_RadiRecoveryFin(void) +{ + debug("%s\n",__FUNCTION__); +#ifdef CONFIG_HTGL + miconCntl_SendCmd(0x70); +#endif +} +#endif + +// --------------------------------------------------------------- +// Disable watchdog timer +void miconCntl_DisWDT(void) +{ + debug("%s\n",__FUNCTION__); + miconCntl_SendCmd(0x41); // A + miconCntl_SendCmd(0x46); // F + miconCntl_SendCmd(0x4A); // J + miconCntl_SendCmd(0x3E); // > + miconCntl_SendCmd(0x56); // V + miconCntl_SendCmd(0x3E); // > + miconCntl_SendCmd(0x5A); // Z + miconCntl_SendCmd(0x56); // V + miconCntl_SendCmd(0x4B); // K +} +// --------------------------------------------------------------- +// U-Boot calls this function +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + disable_interrupts(); + miconCntl_Reboot(); + while (1) + miconCntl_SendUart(0x47); /* Wait for reboot */ + +} + +/* vim: set ts=4: */ diff -urN u-boot-86xx/board/linkstation/ide.c u-boot-86xx-kuro_clean/board/linkstation/ide.c --- u-boot-86xx/board/linkstation/ide.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/ide.c 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,101 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + * + */ +/* ide.c - ide support functions */ + + +#include + +#ifdef CFG_CMD_IDE +#include +#include +#include + +#define IT8212_PCI_CpuCONTROL 0x5e +#define IT8212_PCI_PciModeCONTROL 0x50 +#define IT8212_PCI_IdeIoCONFIG 0x40 +#define IT8212_PCI_IdeBusSkewCONTROL 0x4c +#define IT8212_PCI_IdeDrivingCURRENT 0x42 + +extern ulong ide_bus_offset[CFG_IDE_MAXBUS]; +extern struct pci_controller hose; + +int ide_preinit (void) +{ + int status; + pci_dev_t devbusfn; + int l; + + status = 1; + for (l = 0; l < CFG_IDE_MAXBUS; l++) { + ide_bus_offset[l] = -ATA_STATUS; + } + devbusfn = pci_find_device (PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, 0); + if (devbusfn == -1) + devbusfn = pci_find_device (PCI_VENDOR_ID_ITE,PCI_DEVICE_ID_ITE_8212,0); + if (devbusfn != -1) { + status = 0; + + pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, + (u32 *) &ide_bus_offset[0]); + ide_bus_offset[0] &= 0xfffffffe; + ide_bus_offset[0] = pci_hose_bus_to_phys(&hose, + ide_bus_offset[0] & 0xfffffffe, + PCI_REGION_IO); + pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_2, + (u32 *) &ide_bus_offset[1]); + ide_bus_offset[1] &= 0xfffffffe; + ide_bus_offset[1] = pci_hose_bus_to_phys(&hose, + ide_bus_offset[1] & 0xfffffffe, + PCI_REGION_IO); + } + + if (pci_find_device (PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212, 0) != -1) { + pci_write_config_byte(devbusfn, IT8212_PCI_CpuCONTROL, 0x01); + pci_write_config_byte(devbusfn, IT8212_PCI_PciModeCONTROL, 0x00); + pci_write_config_word(devbusfn, PCI_COMMAND, 0x0047); +#ifdef CONFIG_IT8212_SECONDARY_ENABLE + pci_write_config_word(devbusfn, IT8212_PCI_IdeIoCONFIG, 0xA0F3); +#else + pci_write_config_word(devbusfn, IT8212_PCI_IdeIoCONFIG, 0x8031); +#endif + pci_write_config_dword(devbusfn, IT8212_PCI_IdeBusSkewCONTROL, 0x02040204); +// __LS_COMMENT__ BUFFALO changed 2004.11.10 changed for EMI + pci_write_config_byte(devbusfn, IT8212_PCI_IdeDrivingCURRENT, 0x36); // 10mA +// pci_write_config_byte(dev, IT8212_PCI_IdeDrivingCURRENT, 0x09); // 4mA +// pci_write_config_byte(dev, IT8212_PCI_IdeDrivingCURRENT, 0x12); // 6mA +// pci_write_config_byte(dev, IT8212_PCI_IdeDrivingCURRENT, 0x24); // 6mA,2mA +// pci_write_config_byte(dev, IT8212_PCI_IdeDrivingCURRENT, 0x2D); // 8mA,4mA + pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x00); + } + + return (status); +} + +void ide_set_reset (int flag) { + return; +} + +#endif /* of CONFIG_CMDS_IDE */ + +/* vim: set ts=4: */ diff -urN u-boot-86xx/board/linkstation/linkstation.c u-boot-86xx-kuro_clean/board/linkstation/linkstation.c --- u-boot-86xx/board/linkstation/linkstation.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/linkstation.c 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,127 @@ +/* + * linkstation.c + * + * Misc LinkStation specific functions + * + * Copyright (C) 2006 Mihai Georgin + * + * 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 + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_PCI +#include +#endif + +extern void init_AVR_DUART(void); +extern void hw_watchdog_reset(void); + +int checkboard (void) +{ + DECLARE_GLOBAL_DATA_PTR; + ulong busfreq = get_bus_freq (0); + char buf[32]; + char *p; + bd_t *bd = gd->bd; + + init_AVR_DUART(); + hw_watchdog_reset(); + + if ((p = getenv ("console_nr")) != NULL) { + unsigned long con_nr = simple_strtoul (p, NULL, 10) & 3; + + bd->bi_baudrate &= ~3; + bd->bi_baudrate |= con_nr & 3; + } + return 0; +} + +long int initdram (int board_type) +{ + return (get_ram_size(CFG_SDRAM_BASE, CFG_MAX_RAM_SIZE)); +} + +/* + * Initialize PCI Devices + */ +#ifdef CONFIG_PCI + +#ifndef CONFIG_PCI_PNP + +static struct pci_config_table pci_linkstation_config_table[] = { + /* vendor, device, class */ + /* bus, dev, func */ + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0b, 0, /* AN983B or RTL8110S */ + /* ethernet controller */ + pci_cfgfunc_config_device, { PCI_ETH_IOADDR, + PCI_ETH_MEMADDR, + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0c, 0, /* SII680 or IT8211AF */ + /* ide controller */ + pci_cfgfunc_config_device, { PCI_IDE_IOADDR, + PCI_IDE_MEMADDR, + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0e, 0, /* D720101 USB controller, 1st USB 1.1 */ + pci_cfgfunc_config_device, { PCI_USB0_IOADDR, + PCI_USB0_MEMADDR, + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0e, 1, /* D720101 USB controller, 2nd USB 1.1 */ + pci_cfgfunc_config_device, { PCI_USB1_IOADDR, + PCI_USB1_MEMADDR, + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, 0x0e, 2, /* D720101 USB controller, USB 2.0 */ + pci_cfgfunc_config_device, { PCI_USB2_IOADDR, + PCI_USB2_MEMADDR, + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER }}, + { } +}; +#endif + +struct pci_controller hose = { +#ifndef CONFIG_PCI_PNP + config_table:pci_linkstation_config_table, +#endif +}; + +void pci_init_board (void) +{ + pci_mpc824x_init (&hose); + + /* Reset USB 1.1 */ + out_le32(PCI_USB0_MEMADDR+8, 1); + out_le32(PCI_USB1_MEMADDR+8, 1); + +} +#endif /* CONFIG_PCI */ + +/* vim: set ts=4: */ diff -urN u-boot-86xx/board/linkstation/nc.sh u-boot-86xx-kuro_clean/board/linkstation/nc.sh --- u-boot-86xx/board/linkstation/nc.sh 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/nc.sh 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,10 @@ +#! /bin/bash + +[ $# = 1 ] || { echo "Usage: $0 target_ip" >&2 ; exit 1 ; } +TARGET_IP=$1 + +stty -icanon -echo intr ^T +#nc -u -l -p 6666 < /dev/null & +nc -u -p 6666 -v -v ${TARGET_IP} 6666 +stty icanon echo intr ^C + diff -urN u-boot-86xx/board/linkstation/u-boot.lds u-boot-86xx-kuro_clean/board/linkstation/u-boot.lds --- u-boot-86xx/board/linkstation/u-boot.lds 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/board/linkstation/u-boot.lds 2006-11-06 22:05:38.000000000 +0100 @@ -0,0 +1,138 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ + +OUTPUT_ARCH(powerpc) +/* +SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); SEARCH_DIR(/usr/lib/gcc-lib/ppc-linux/3.3.3); +*/ +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/mpc824x/start.o (.text) + lib_ppc/board.o (.text) + lib_ppc/ppcstring.o (.text) + lib_generic/vsprintf.o (.text) + lib_generic/crc32.o (.text) + lib_generic/zlib.o (.text) + + . = DEFINED(env_offset) ? env_offset : .; + common/environment.o (.text) + + *(.text) + + *(.fixup) + *(.got1) + . = ALIGN(16); + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + + _end = . ; + PROVIDE (end = .); +} diff -urN u-boot-86xx/common/cmd_bootm.c u-boot-86xx-kuro_clean/common/cmd_bootm.c --- u-boot-86xx/common/cmd_bootm.c 2006-10-13 00:27:16.000000000 +0200 +++ u-boot-86xx-kuro_clean/common/cmd_bootm.c 2006-11-06 22:05:38.000000000 +0100 @@ -193,6 +193,12 @@ verify = 0; } else #endif /* __I386__ */ +#ifdef CONFIG_LINKSTATION + extern boot_os_Fcn do_boot_lskernel; + do_boot_lskernel(cmdtp, flag, argc, argv, + addr, NULL, verify); + return 1; /* Only returns on error */ +#endif { puts ("Bad Magic Number\n"); SHOW_BOOT_PROGRESS (-1); diff -urN u-boot-86xx/common/cmd_ext2.c u-boot-86xx-kuro_clean/common/cmd_ext2.c --- u-boot-86xx/common/cmd_ext2.c 2006-10-13 00:27:16.000000000 +0200 +++ u-boot-86xx-kuro_clean/common/cmd_ext2.c 2006-11-06 22:05:38.000000000 +0100 @@ -283,7 +283,8 @@ sprintf(buf, "%lX", filelen); setenv("filesize", buf); - return(filelen); +// return(filelen); + return(0); } U_BOOT_CMD( diff -urN u-boot-86xx/common/console.c u-boot-86xx-kuro_clean/common/console.c --- u-boot-86xx/common/console.c 2006-10-13 00:27:16.000000000 +0200 +++ u-boot-86xx-kuro_clean/common/console.c 2006-11-06 22:05:38.000000000 +0100 @@ -48,7 +48,7 @@ #endif /* CFG_CONSOLE_IS_IN_ENV */ -static int console_setfile (int file, device_t * dev) +int console_setfile (int file, device_t * dev) { int error = 0; @@ -444,22 +444,27 @@ gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ #ifndef CFG_CONSOLE_INFO_QUIET + if (strcmp(stdio_devices[stdout]->name, "serial")) { + extern char version_string[]; + printf ("\n%s\n", version_string); + } + /* Print information */ - puts ("In: "); + puts ("stdin : "); if (stdio_devices[stdin] == NULL) { puts ("No input devices available!\n"); } else { printf ("%s\n", stdio_devices[stdin]->name); } - puts ("Out: "); + puts ("stdout: "); if (stdio_devices[stdout] == NULL) { puts ("No output devices available!\n"); } else { printf ("%s\n", stdio_devices[stdout]->name); } - puts ("Err: "); + puts ("stderr: "); if (stdio_devices[stderr] == NULL) { puts ("No error devices available!\n"); } else { diff -urN u-boot-86xx/common/main.c u-boot-86xx-kuro_clean/common/main.c --- u-boot-86xx/common/main.c 2006-10-13 00:27:16.000000000 +0200 +++ u-boot-86xx-kuro_clean/common/main.c 2006-11-06 22:05:38.000000000 +0100 @@ -84,6 +84,11 @@ extern void mdm_init(void); /* defined in board.c */ #endif +#ifdef CONFIG_LINKSTATION +extern int avr_input(void); +extern void avr_StopBoot(void); +#endif + /*************************************************************************** * Watch for 'delay' seconds for autoboot stop or autoboot delay string. * returns: 0 - no key string, allow autoboot @@ -162,7 +167,14 @@ /* In order to keep up with incoming data, check timeout only * when catch up. */ + uint64_t onesec = endtick(1); + int bootremain = bootdelay; while (!abort && get_ticks() <= etime) { + if (get_ticks() >= onesec) { + onesec = endtick(1); + putc('\r'); + printf (CONFIG_AUTOBOOT_PROMPT, --bootremain); + } for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) { if (delaykey[i].len > 0 && presskey_len >= delaykey[i].len && @@ -183,6 +195,20 @@ } } +#ifdef CONFIG_LINKSTATION + int avr_action = avr_input(); + if (avr_action == -3) + /* Abort boot */ + abort = 1; + else if (avr_action == -2) { + /* Restart boot */ + putc('\r'); + printf (CONFIG_AUTOBOOT_PROMPT, bootdelay); + etime = endtick(bootdelay); + onesec = endtick(1); + bootremain = bootdelay; + } +#endif if (tstc()) { if (presskey_len < presskey_max) { presskey [presskey_len ++] = getc(); @@ -195,6 +221,7 @@ } } } + putc('\n'); # if DEBUG_BOOTKEYS if (!abort) puts ("key timeout\n"); @@ -411,6 +438,10 @@ int prev = disable_ctrlc(1); /* disable Control C checking */ # endif +#ifdef CONFIG_LINKSTATION + s = getenv("bootcmd"); /* bootcmd can change (see avr.c) */ +#endif + # ifndef CFG_HUSH_PARSER run_command (s, 0); # else @@ -445,6 +476,10 @@ } #endif +#ifdef CONFIG_LINKSTATION + avr_StopBoot(); +#endif + /* * Main Loop for Monitor Command Processing */ @@ -469,6 +504,10 @@ strcpy (lastcommand, console_buffer); else if (len == 0) flag |= CMD_FLAG_REPEAT; +#ifdef CONFIG_LINKSTATION + else if (len == -2) + return; +#endif #ifdef CONFIG_BOOT_RETRY_TIME else if (len == -2) { /* -2 means timed out, retry autoboot @@ -978,6 +1017,15 @@ show_activity(0); } #endif +#ifdef CONFIG_LINKSTATION + while (!tstc()) { + int avr_ret = avr_input(); + if (avr_ret == -2) + return (-2); + else if (avr_ret > 0) + return avr_ret; + } +#endif c = getc(); /* diff -urN u-boot-86xx/cpu/mpc824x/cpu.c u-boot-86xx-kuro_clean/cpu/mpc824x/cpu.c --- u-boot-86xx/cpu/mpc824x/cpu.c 2006-10-13 00:27:17.000000000 +0200 +++ u-boot-86xx-kuro_clean/cpu/mpc824x/cpu.c 2006-11-06 22:05:38.000000000 +0100 @@ -92,6 +92,7 @@ /*------------------------------------------------------------------- */ +#ifndef CONFIG_LINKSTATION int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong msr, addr; @@ -125,6 +126,7 @@ return 1; } +#endif /* ------------------------------------------------------------------------- */ diff -urN u-boot-86xx/cpu/mpc824x/start.S u-boot-86xx-kuro_clean/cpu/mpc824x/start.S --- u-boot-86xx/cpu/mpc824x/start.S 2006-10-13 00:27:17.000000000 +0200 +++ u-boot-86xx-kuro_clean/cpu/mpc824x/start.S 2006-11-06 22:05:38.000000000 +0100 @@ -130,7 +130,7 @@ in_flash: -#if defined(CONFIG_BMW) +#if defined(CONFIG_BMW) || defined(CONFIG_LINKSTATION) bl early_init_f /* Must be ASM: no stack yet! */ #endif /* @@ -155,6 +155,7 @@ mtspr HID0, r2 sync +#if !defined(CONFIG_LINKSTATION) /* Allocate Initial RAM in data cache. */ lis r3, CFG_INIT_RAM_ADDR@h @@ -175,6 +176,7 @@ ori r3, r3, 0x0080 sync mtspr 1011, r3 +#endif /* !CONFIG_LINKSTATION */ #endif /* !CONFIG_BMW */ /* * Thisk the stack pointer *somewhere* sensible. Doesnt @@ -195,7 +197,9 @@ GET_GOT /* initialize GOT access */ /* r3: IMMR */ +#if !defined(CONFIG_LINKSTATION) bl cpu_init_f /* run low-level CPU init code (from Flash) */ +#endif mr r3, r21 /* r3: BOOTFLAG */ @@ -475,7 +479,7 @@ mr r10, r5 /* Save copy of Destination Address */ mr r3, r5 /* Destination Address */ -#ifdef CFG_RAMBOOT +#if defined(CFG_RAMBOOT) && !defined(CONFIG_LINKSTATION) lis r4, CFG_SDRAM_BASE@h /* Source Address */ ori r4, r4, CFG_SDRAM_BASE@l #else @@ -689,6 +693,14 @@ cmplw 0, r7, r8 blt 4b + mfmsr r7 /* Exception prefix 0x000 */ + li r8,0 + ori r8,r8,MSR_IP + andc r7,r7,r8 + SYNC + mtmsr r7 + SYNC + mtlr r4 /* restore link register */ blr diff -urN u-boot-86xx/drivers/dc2114x.c u-boot-86xx-kuro_clean/drivers/dc2114x.c --- u-boot-86xx/drivers/dc2114x.c 2006-10-13 00:27:17.000000000 +0200 +++ u-boot-86xx-kuro_clean/drivers/dc2114x.c 2006-11-06 22:05:38.000000000 +0100 @@ -27,14 +27,20 @@ #include #include +#if 0 +#define DEBUG_TRACE +#define DEBUG_TULIP +#endif + #undef DEBUG_SROM #undef DEBUG_SROM2 #undef UPDATE_SROM -/* PCI Registers. +/* + * PCI Registers. */ -#define PCI_CFDA_PSM 0x43 +#define PCI_CFDA_PSM 0x43 #define CFRV_RN 0x000000f0 /* Revision Number */ @@ -43,10 +49,12 @@ #define DC2114x_BRK 0x0020 /* CFRV break between DC21142 & DC21143 */ -/* Ethernet chip registers. +/* + * Ethernet chip registers. */ #define DE4X5_BMR 0x000 /* Bus Mode Register */ #define DE4X5_TPD 0x008 /* Transmit Poll Demand Reg */ +#define DE4X5_RPD 0x010 /* Receive Poll Demand Reg */ #define DE4X5_RRBA 0x018 /* RX Ring Base Address Reg */ #define DE4X5_TRBA 0x020 /* TX Ring Base Address Reg */ #define DE4X5_STS 0x028 /* Status Register */ @@ -54,7 +62,8 @@ #define DE4X5_SICR 0x068 /* SIA Connectivity Register */ #define DE4X5_APROM 0x048 /* Ethernet Address PROM */ -/* Register bits. +/* + * Register bits. */ #define BMR_SWR 0x00000001 /* Software Reset */ #define STS_TS 0x00700000 /* Transmit Process State */ @@ -64,8 +73,10 @@ #define OMR_PS 0x00040000 /* Port Select */ #define OMR_SDP 0x02000000 /* SD Polarity - MUST BE ASSERTED */ #define OMR_PM 0x00000080 /* Pass All Multicast */ +#define OMR_PMS 0x00000040 /* Promiscuous */ -/* Descriptor bits. +/* + * Descriptor bits. */ #define R_OWN 0x80000000 /* Own Bit */ #define RD_RER 0x02000000 /* Receive End Of Ring */ @@ -85,10 +96,10 @@ #define SROM_HWADD 0x0014 /* Hardware Address offset in SROM */ #define SROM_RD 0x00004000 /* Read from Boot ROM */ -#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ +#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ #define EE_WRITE_0 0x4801 #define EE_WRITE_1 0x4805 -#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ +#define EE_DATA_READ 0x08 /* EEPROM chip data out. */ #define SROM_SR 0x00000800 /* Select Serial ROM when set */ #define DT_IN 0x00000004 /* Serial Data In */ @@ -97,6 +108,36 @@ #define POLL_DEMAND 1 +#ifndef PCI_VENDOR_ID_ADMTEK +# define PCI_VENDOR_ID_ADMTEK 0x1317 +#endif +#ifndef PCI_DEVICE_ID_ADMTEK_AN983B +# define PCI_DEVICE_ID_ADMTEK_AN983B 0x985 +#endif + +/* The chip types have been taken from linux-2.4.31 + * drivers/net/tulip/tulip.h + * Only COMET is used for now + */ +enum chips { + DC21040 = 0, + DC21041 = 1, + DC21140 = 2, + DC21142 = 3, DC21143 = 3, + LC82C168, + MX98713, + MX98715, + MX98725, + AX88140, + PNIC2, + COMET, + COMPEX9881, + I21145, + DM910X, + CONEXANT, +}; +static int chip_idx = DC21143; + #ifdef CONFIG_TULIP_FIX_DAVICOM #define RESET_DM9102(dev) {\ unsigned long i;\ @@ -108,58 +149,63 @@ #else #define RESET_DE4X5(dev) {\ int i;\ - i=INL(dev, DE4X5_BMR);\ - udelay(1000);\ + i=0x01A04000;\ OUTL(dev, i | BMR_SWR, DE4X5_BMR);\ udelay(1000);\ OUTL(dev, i, DE4X5_BMR);\ udelay(1000);\ - for (i=0;i<5;i++) {INL(dev, DE4X5_BMR); udelay(10000);}\ - udelay(1000);\ } #endif #define START_DE4X5(dev) {\ - s32 omr; \ + u32 omr; \ omr = INL(dev, DE4X5_OMR);\ omr |= OMR_ST | OMR_SR;\ OUTL(dev, omr, DE4X5_OMR); /* Enable the TX and/or RX */\ } #define STOP_DE4X5(dev) {\ - s32 omr; \ + u32 omr; \ omr = INL(dev, DE4X5_OMR);\ omr &= ~(OMR_ST|OMR_SR);\ OUTL(dev, omr, DE4X5_OMR); /* Disable the TX and/or RX */ \ } -#define NUM_RX_DESC PKTBUFSRX +#define NUM_RX_DESC 4 #ifndef CONFIG_TULIP_FIX_DAVICOM - #define NUM_TX_DESC 1 /* Number of TX descriptors */ + #define NUM_TX_DESC 2 /* Number of TX descriptors */ #else #define NUM_TX_DESC 4 #endif -#define RX_BUFF_SZ PKTSIZE_ALIGN +#define BUFLEN 1536 #define TOUT_LOOP 1000000 #define SETUP_FRAME_LEN 192 #define ETH_ALEN 6 +#define ETH_ZLEN 60 struct de4x5_desc { - volatile s32 status; + volatile u32 status; u32 des1; u32 buf; u32 next; }; -static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(32))); /* RX descriptor ring */ -static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(32))); /* TX descriptor ring */ -static int rx_new; /* RX descriptor ring pointer */ -static int tx_new; /* TX descriptor ring pointer */ +/* Note: transmit and receive buffers must be longword aligned and + longword divisable */ -static char rxRingSize; -static char txRingSize; +/* TX descriptor ring */ +static struct de4x5_desc tx_ring[NUM_TX_DESC] __attribute__ ((aligned(4))); +/* TX buffer */ +static unsigned char txb[BUFLEN] __attribute__ ((aligned(32))); + +/* RX descriptor ring */ +static struct de4x5_desc rx_ring[NUM_RX_DESC] __attribute__ ((aligned(4))); +/* RX buffers */ +static unsigned char rxb[NUM_RX_DESC * BUFLEN] __attribute__ ((aligned(32))); + +static int rx_new; /* RX descriptor ring pointer */ #if defined(UPDATE_SROM) || !defined(CONFIG_TULIP_FIX_DAVICOM) static void sendto_srom(struct eth_device* dev, u_int command, u_long addr); @@ -204,6 +250,7 @@ static struct pci_device_id supported[] = { { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST }, { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142 }, + { PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_AN983B }, #ifdef CONFIG_TULIP_FIX_DAVICOM { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DAVICOM_DM9102A }, #endif @@ -214,29 +261,44 @@ { int idx=0; int card_number = 0; - unsigned int cfrv; + unsigned int cfrv; unsigned char timer; - pci_dev_t devbusfn; + pci_dev_t devbusfn; unsigned int iobase; unsigned short status; struct eth_device* dev; + u16 vendor; + u16 device; +#ifdef DEBUG_TULIP + printf("%s\n", __FUNCTION__); +#endif while(1) { devbusfn = pci_find_devices(supported, idx++); if (devbusfn == -1) { break; } + pci_read_config_word(devbusfn, PCI_VENDOR_ID, &vendor); + pci_read_config_word(devbusfn, PCI_DEVICE_ID, &device); - /* Get the chip configuration revision register. */ - pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv); + debug("dc21x4x: devbusfn: %08lX, VID: %08lX, DID: %08lX\n", + devbusfn, vendor, device); + + if (vendor == PCI_VENDOR_ID_ADMTEK && \ + device == PCI_DEVICE_ID_ADMTEK_AN983B) { + chip_idx = COMET; + } else { + /* Get the chip configuration revision register. */ + pci_read_config_dword(devbusfn, PCI_REVISION_ID, &cfrv); #ifndef CONFIG_TULIP_FIX_DAVICOM - if ((cfrv & CFRV_RN) < DC2114x_BRK ) { - printf("Error: The chip is not DC21143.\n"); - continue; - } + if ((cfrv & CFRV_RN) < DC2114x_BRK ) { + printf("Error: The chip is not DC21143.\n"); + idx++; + continue; + } #endif - + } pci_read_config_word(devbusfn, PCI_COMMAND, &status); status |= #ifdef CONFIG_TULIP_USE_IO @@ -286,7 +348,10 @@ #ifdef CONFIG_TULIP_FIX_DAVICOM sprintf(dev->name, "Davicom#%d", card_number); #else - sprintf(dev->name, "dc21x4x#%d", card_number); + if (chip_idx == COMET) + sprintf(dev->name, "COMET#%d", card_number); + else + sprintf(dev->name, "dc21x4x#%d", card_number); #endif #ifdef CONFIG_TULIP_USE_IO @@ -303,8 +368,6 @@ /* Ensure we're not sleeping. */ pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); - udelay(10 * 1000); - #ifndef CONFIG_TULIP_FIX_DAVICOM read_hw_addr(dev, bis); #endif @@ -321,8 +384,9 @@ int i; int devbusfn = (int) dev->priv; - /* Ensure we're not sleeping. */ - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, WAKEUP); +#if defined(DEBUG_TULIP) || defined(DEBUG_TRACE) + serial_printf("%0lu %s\n", get_timer(0), __FUNCTION__); +#endif #ifdef CONFIG_TULIP_FIX_DAVICOM RESET_DM9102(dev); @@ -330,57 +394,71 @@ RESET_DE4X5(dev); #endif - if ((INL(dev, DE4X5_STS) & (STS_TS | STS_RS)) != 0) { - printf("Error: Cannot reset ethernet controller.\n"); - return 0; - } - #ifdef CONFIG_TULIP_SELECT_MEDIA dc21x4x_select_media(dev); #else - OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); + if (chip_idx == COMET) { + /* No multicast */ + OUTL(dev, 0, 0xAC); + OUTL(dev, 0, 0xB0); + } else { + OUTL(dev, OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR); + } #endif for (i = 0; i < NUM_RX_DESC; i++) { rx_ring[i].status = cpu_to_le32(R_OWN); - rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ); - rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i])); -#ifdef CONFIG_TULIP_FIX_DAVICOM - rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC])); -#else - rx_ring[i].next = 0; -#endif + rx_ring[i].des1 = cpu_to_le32(BUFLEN); + rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32)&rxb[i * BUFLEN])); + rx_ring[i].next = cpu_to_le32(phys_to_bus((u32)&rx_ring[i+1])); } + /* Write the end of list marker to the descriptor lists. */ + rx_ring[NUM_RX_DESC - 1].des1 |= cpu_to_le32(RD_RER); + rx_ring[NUM_RX_DESC - 1].next = cpu_to_le32(phys_to_bus((u32)&rx_ring[0])); - for (i=0; i < NUM_TX_DESC; i++) { - tx_ring[i].status = 0; - tx_ring[i].des1 = 0; - tx_ring[i].buf = 0; + /* Point to the first descriptor */ + rx_new = 0; -#ifdef CONFIG_TULIP_FIX_DAVICOM - tx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &tx_ring[(i+1) % NUM_TX_DESC])); -#else - tx_ring[i].next = 0; -#endif - } + /* We only use 1 transmit buffer, but we use 2 descriptors so + transmit engines have somewhere to point to if they feel the need */ - rxRingSize = NUM_RX_DESC; - txRingSize = NUM_TX_DESC; + tx_ring[0].status = 0; + tx_ring[0].des1 = 0; + tx_ring[0].buf = cpu_to_le32(phys_to_bus((u32)&txb[0])); + tx_ring[0].next = cpu_to_le32(phys_to_bus((u32)&tx_ring[1])); + + /* this descriptor should never get used, since it will never be owned + by the machine (status will always == 0) */ + + tx_ring[1].status = 0; + tx_ring[1].des1 = 0; + tx_ring[1].buf = cpu_to_le32(phys_to_bus((u32)&txb[0])); + tx_ring[1].next = cpu_to_le32(phys_to_bus((u32)&tx_ring[0])); /* Write the end of list marker to the descriptor lists. */ - rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER); - tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER); + tx_ring[1].des1 |= cpu_to_le32(TD_TER); /* Tell the adapter where the TX/RX rings are located. */ - OUTL(dev, phys_to_bus((u32) &rx_ring), DE4X5_RRBA); - OUTL(dev, phys_to_bus((u32) &tx_ring), DE4X5_TRBA); + OUTL(dev, phys_to_bus((u32) &rx_ring[0]), DE4X5_RRBA); + OUTL(dev, phys_to_bus((u32) &tx_ring[0]), DE4X5_TRBA); + + if (chip_idx == COMET) { + /* Bit 18 (0x00040000) is reserved in the AN983B */ + /* datasheet, but it is used by the tulip driver */ + OUTL(dev, (INL(dev, (DE4X5_OMR)) & ~(OMR_PMS | OMR_PM)) | OMR_PS, DE4X5_OMR); + /* Enable automatic Tx underrun recovery */ + OUTL(dev, INL(dev, 0x88) | 1, 0x88); +// OUTL(dev, INL(dev, 0x88) | 0x19, 0x88); + } START_DE4X5(dev); - tx_new = 0; - rx_new = 0; + /* Start receiving */ + OUTL(dev, POLL_DEMAND, DE4X5_RPD); - send_setup_frame(dev, bis); + if (chip_idx != COMET) { /* No setup frame needed by COMET */ + send_setup_frame(dev, bis); + } return 1; } @@ -389,90 +467,117 @@ { int status = -1; int i; + u32 len = length; if (length <= 0) { printf("%s: bad packet size: %d\n", dev->name, length); goto Done; } - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + for(i = 0; tx_ring[0].status & cpu_to_le32(T_OWN); i++) { if (i >= TOUT_LOOP) { - printf("%s: tx error buffer not ready\n", dev->name); + printf(".%s: Tx not ready\n", dev->name); goto Done; } } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) packet)); - tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length); - tx_ring[tx_new].status = cpu_to_le32(T_OWN); + /* Disable the TX */ + OUTL(dev, INL(dev, DE4X5_OMR) & ~OMR_ST, DE4X5_OMR); + + memcpy(txb, (char*)packet, length); + + /* setup the transmit descriptor */ + tx_ring[0].des1 = cpu_to_le32(TD_LS | TD_FS | length); + tx_ring[0].status = cpu_to_le32(T_OWN); + /* Point to transmit descriptor */ + OUTL(dev, phys_to_bus((u32) &tx_ring[0]), DE4X5_TRBA); + + /* Enable the TX */ + OUTL(dev, INL(dev, DE4X5_OMR) | OMR_ST, DE4X5_OMR); + + /* Immediate transmit demand */ OUTL(dev, POLL_DEMAND, DE4X5_TPD); - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + for(i = 0; tx_ring[0].status & cpu_to_le32(T_OWN); i++) { if (i >= TOUT_LOOP) { - printf(".%s: tx buffer not ready\n", dev->name); + printf(".%s: Tx Timeout\n", dev->name); goto Done; } } - if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES) { -#if 0 /* test-only */ +#ifdef DEBUG_TRACE + serial_printf("%0lu Tx L2: %d P: %04X IP: %08X\n", + get_timer(0), i, *((u16 *)(packet+0xC)), + *((u32 *)(packet+0x1E))); +#endif + + if (le32_to_cpu(tx_ring[0].status) & TD_ES) { +#if 1 /* test-only */ printf("TX error status = 0x%08X\n", - le32_to_cpu(tx_ring[tx_new].status)); + le32_to_cpu(tx_ring[0].status)); #endif - tx_ring[tx_new].status = 0x0; + tx_ring[0].status = 0x0; goto Done; } status = length; Done: - tx_new = (tx_new+1) % NUM_TX_DESC; return status; } static int dc21x4x_recv(struct eth_device* dev) { - s32 status; + u32 status; + int rx_prv; int length = 0; - for ( ; ; ) { - status = (s32)le32_to_cpu(rx_ring[rx_new].status); +#ifdef DEBUG_TULIP + u32 csr5 = INL(dev, DE4X5_STS); + if ((csr5 & STS_RS) != 0x00060000) { + OUTL(dev, 0x0001ffff, DE4X5_STS); + printf("Receive status: 0x%08X\n", csr5); + } +#endif - if (status & R_OWN) { - break; - } + status = (u32)le32_to_cpu(rx_ring[rx_new].status); + if (status & R_OWN) + return 0; - if (status & RD_LS) { - /* Valid frame status. - */ - if (status & RD_ES) { - - /* There was an error. - */ - printf("RX error status = 0x%08X\n", status); - } else { - /* A valid frame received. - */ - length = (le32_to_cpu(rx_ring[rx_new].status) >> 16); - - /* Pass the packet up to the protocol - * layers. - */ - NetReceive(NetRxPackets[rx_new], length - 4); - } +#ifdef DEBUG_TULIP + printf("recv status: 0x%08X\n", status); +#endif - /* Change buffer ownership for this frame, back - * to the adapter. - */ + if (status & RD_LS) { +#ifdef DEBUG_TRACE + serial_printf("rx: %d status: %08X\n", rx_new, status); +#endif + /* Valid frame status */ + if (status & RD_ES) { + /* There was an error */ + printf("RX error status = 0x%08X\n", status); rx_ring[rx_new].status = cpu_to_le32(R_OWN); - } + } else { + /* Received valid frame */ + length = (int)(le32_to_cpu(rx_ring[rx_new].status) >> 16); + + /* Pass the packet up to the protocol layers. */ + unsigned char rxdata[BUFLEN]; + memcpy(rxdata, rxb + rx_new * BUFLEN, length - 4); - /* Update entry information. - */ - rx_new = (rx_new + 1) % rxRingSize; + /* Give buffer ownership for this + * frame back to the adapter */ + rx_ring[rx_new].status = cpu_to_le32(R_OWN); + + /* Pass the received packet to the upper layer */ + NetReceive(rxdata, length - 4); + } } + /* Update current descriptor index */ + rx_new = (rx_new + 1) % NUM_RX_DESC; + return length; } @@ -480,10 +585,12 @@ { int devbusfn = (int) dev->priv; +#ifdef DEBUG_TULIP + printf("%s\n", __FUNCTION__); +#endif STOP_DE4X5(dev); OUTL(dev, 0, DE4X5_SICR); - pci_write_config_byte(devbusfn, PCI_CFDA_PSM, SLEEP); } static void send_setup_frame(struct eth_device* dev, bd_t *bis) @@ -501,30 +608,29 @@ } } - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + for(i = 0; tx_ring[0].status & cpu_to_le32(T_OWN); i++) { if (i >= TOUT_LOOP) { printf("%s: tx error buffer not ready\n", dev->name); goto Done; } } - tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0])); - tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN); - tx_ring[tx_new].status = cpu_to_le32(T_OWN); + tx_ring[0].buf = cpu_to_le32(phys_to_bus((u32) &setup_frame[0])); + tx_ring[0].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN); + tx_ring[0].status = cpu_to_le32(T_OWN); OUTL(dev, POLL_DEMAND, DE4X5_TPD); - for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) { + for(i = 0; tx_ring[0].status & cpu_to_le32(T_OWN); i++) { if (i >= TOUT_LOOP) { printf("%s: tx buffer not ready\n", dev->name); goto Done; } } - if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) { - printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status)); + if (le32_to_cpu(tx_ring[0].status) != 0x7FFFFFFF) { + printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[0].status)); } - tx_new = (tx_new+1) % NUM_TX_DESC; Done: return; @@ -543,7 +649,7 @@ static int getfrom_srom(struct eth_device* dev, u_long addr) { - s32 tmp; + u32 tmp; tmp = INL(dev, addr); udelay(1); @@ -708,19 +814,27 @@ #ifndef CONFIG_TULIP_FIX_DAVICOM static void read_hw_addr(struct eth_device *dev, bd_t *bis) { - u_short tmp, *p = (u_short *)(&dev->enetaddr[0]); - int i, j = 0; - - for (i = 0; i < (ETH_ALEN >> 1); i++) { - tmp = read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1) + i)); - *p = le16_to_cpu(tmp); - j += *p++; - } - - if ((j == 0) || (j == 0x2fffd)) { - memset (dev->enetaddr, 0, ETH_ALEN); - debug ("Warning: can't read HW address from SROM.\n"); - goto Done; + if (chip_idx == COMET) { + /* COMET reads the ehernet address directly from the EEPROM */ + *(u32 *)dev->enetaddr = cpu_to_le32(INL(dev, 0xA4)); + *(u16 *)(dev->enetaddr+4) = cpu_to_le16(INL(dev, 0xA8)); + *(u32 *)bis->bi_enetaddr = *(u32 *)dev->enetaddr; + *(u16 *)(bis->bi_enetaddr+4) = *(u16 *)(dev->enetaddr+4); + } else { + u_short tmp, *p = (u_short *)(&dev->enetaddr[0]); + int i, j = 0; + + for (i = 0; i < (ETH_ALEN >> 1); i++) { + tmp=read_srom(dev, DE4X5_APROM, ((SROM_HWADD >> 1)+i)); + *p = le16_to_cpu(tmp); + j += *p++; + } + + if ((j == 0) || (j == 0x2fffd)) { + memset (dev->enetaddr, 0, ETH_ALEN); + debug ("Warning: can't read HW address from SROM.\n"); + goto Done; + } } return; @@ -769,3 +883,5 @@ #endif /* UPDATE_SROM */ #endif /* CFG_CMD_NET && CONFIG_NET_MULTI && CONFIG_TULIP */ + +/* vim: set ts=4: */ diff -urN u-boot-86xx/drivers/netconsole.c u-boot-86xx-kuro_clean/drivers/netconsole.c --- u-boot-86xx/drivers/netconsole.c 2006-10-13 00:27:17.000000000 +0200 +++ u-boot-86xx-kuro_clean/drivers/netconsole.c 2006-11-06 22:05:38.000000000 +0100 @@ -27,6 +27,7 @@ #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -124,6 +125,26 @@ output_packet_len = len; NetLoop (NETCONS); /* wait for arp reply and send packet */ output_packet_len = 0; +#if defined(CFG_CONSOLE_IS_IN_ENV) || defined(CONFIG_SILENT_CONSOLE) + if (NetState == NETLOOP_FAIL) { + /* ARP failed, fail back to serial console */ + device_t *idev; + device_t *odev; + + idev = search_device(DEV_FLAGS_INPUT, "serial"); + odev = search_device(DEV_FLAGS_OUTPUT, "serial"); + + console_setfile (stdin, idev); + console_setfile (stdout, odev); + console_setfile (stderr, odev); + +#if defined(CONFIG_LINKSTATION) + void next_cons_choice(int console); + /* Console 0 is the serial console */ + next_cons_choice(0); +#endif + } +#endif return; } @@ -236,7 +257,8 @@ input_recursion = 1; - net_timeout = 1; +// net_timeout = 1; + net_timeout = 50; NetLoop (NETCONS); /* kind of poll */ input_recursion = 0; diff -urN u-boot-86xx/drivers/rtl8169.c u-boot-86xx-kuro_clean/drivers/rtl8169.c --- u-boot-86xx/drivers/rtl8169.c 2006-10-13 00:27:17.000000000 +0200 +++ u-boot-86xx-kuro_clean/drivers/rtl8169.c 2006-11-06 22:05:38.000000000 +0100 @@ -48,7 +48,10 @@ * * Indent Options: indent -kr -i8 ***************************************************************************/ - +/* + * 26 August 2006 Mihai Georgian + * Modified to use le32_to_cpu and cpu_to_le32 properly + */ #include #include #include @@ -68,6 +71,7 @@ static u32 ioaddr; /* Condensed operations for readability. */ +#define virt_to_bus(addr) cpu_to_le32(addr) #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr)) #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr)) @@ -413,23 +417,23 @@ ioaddr = dev->iobase; cur_rx = tpc->cur_rx; - if ((tpc->RxDescArray[cur_rx].status & OWNbit) == 0) { - if (!(tpc->RxDescArray[cur_rx].status & RxRES)) { + if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) { + if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) { unsigned char rxdata[RX_BUF_LEN]; - length = (int) (tpc->RxDescArray[cur_rx]. - status & 0x00001FFF) - 4; + length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx]. + status) & 0x00001FFF) - 4; memcpy(rxdata, tpc->RxBufferRing[cur_rx], length); NetReceive(rxdata, length); if (cur_rx == NUM_RX_DESC - 1) tpc->RxDescArray[cur_rx].status = - (OWNbit | EORbit) + RX_BUF_SIZE; + cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); else tpc->RxDescArray[cur_rx].status = - OWNbit + RX_BUF_SIZE; + cpu_to_le32(OWNbit + RX_BUF_SIZE); tpc->RxDescArray[cur_rx].buf_addr = - virt_to_bus(tpc->RxBufferRing[cur_rx]); + cpu_to_le32(tpc->RxBufferRing[cur_rx]); } else { puts("Error Rx"); } @@ -454,6 +458,7 @@ u8 *ptxb; int entry = tpc->cur_tx % NUM_TX_DESC; u32 len = length; + int ret; #ifdef DEBUG_RTL8169_TX int stime = currticks(); @@ -465,39 +470,46 @@ /* point to the current txb incase multiple tx_rings are used */ ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE]; +#ifdef DEBUG_RTL8169_TX + printf("ptxb: %08X, length: %d\n", ptxb, (int)length); +#endif memcpy(ptxb, (char *)packet, (int)length); while (len < ETH_ZLEN) ptxb[len++] = '\0'; - tpc->TxDescArray[entry].buf_addr = virt_to_bus(ptxb); + tpc->TxDescArray[entry].buf_addr = cpu_to_le32(ptxb); if (entry != (NUM_TX_DESC - 1)) { tpc->TxDescArray[entry].status = - (OWNbit | FSbit | LSbit) | ((len > ETH_ZLEN) ? - len : ETH_ZLEN); + cpu_to_le32((OWNbit | FSbit | LSbit) | + ((len > ETH_ZLEN) ? len : ETH_ZLEN)); } else { tpc->TxDescArray[entry].status = - (OWNbit | EORbit | FSbit | LSbit) | - ((len > ETH_ZLEN) ? length : ETH_ZLEN); + cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) | + ((len > ETH_ZLEN) ? len : ETH_ZLEN)); } RTL_W8(TxPoll, 0x40); /* set polling bit */ tpc->cur_tx++; to = currticks() + TX_TIMEOUT; - while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */ + while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit) + && (currticks() < to)); /* wait */ if (currticks() >= to) { #ifdef DEBUG_RTL8169_TX puts ("tx timeout/error\n"); printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); #endif - return 0; + ret = 0; } else { #ifdef DEBUG_RTL8169_TX puts("tx done\n"); #endif - return length; + ret = length; } + /* Delay to make net console (nc) work properly */ + udelay(20); + return ret; } static void rtl8169_set_rx_mode(struct eth_device *dev) @@ -603,13 +615,14 @@ for (i = 0; i < NUM_RX_DESC; i++) { if (i == (NUM_RX_DESC - 1)) tpc->RxDescArray[i].status = - (OWNbit | EORbit) + RX_BUF_SIZE; + cpu_to_le32((OWNbit | EORbit) + RX_BUF_SIZE); else - tpc->RxDescArray[i].status = OWNbit + RX_BUF_SIZE; + tpc->RxDescArray[i].status = + cpu_to_le32(OWNbit + RX_BUF_SIZE); tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; tpc->RxDescArray[i].buf_addr = - virt_to_bus(tpc->RxBufferRing[i]); + cpu_to_le32(tpc->RxBufferRing[i]); } #ifdef DEBUG_RTL8169 @@ -635,17 +648,23 @@ if (tpc->TxDescArrays == 0) puts("Allot Error"); /* Tx Desscriptor needs 256 bytes alignment; */ - TxPhyAddr = virt_to_bus(tpc->TxDescArrays); + TxPhyAddr = tpc->TxDescArrays; diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8)); TxPhyAddr += diff; tpc->TxDescArray = (struct TxDesc *) (tpc->TxDescArrays + diff); +#ifdef DEBUG_RTL8169 + printf("tpc->TxDescArray: %08X\n", tpc->TxDescArray); +#endif tpc->RxDescArrays = rx_ring; /* Rx Desscriptor needs 256 bytes alignment; */ - RxPhyAddr = virt_to_bus(tpc->RxDescArrays); + RxPhyAddr = tpc->RxDescArrays; diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8)); RxPhyAddr += diff; tpc->RxDescArray = (struct RxDesc *) (tpc->RxDescArrays + diff); +#ifdef DEBUG_RTL8169 + printf("tpc->RxDescArray: %08X\n", tpc->RxDescArray); +#endif if (tpc->TxDescArrays == NULL || tpc->RxDescArrays == NULL) { puts("Allocate RxDescArray or TxDescArray failed\n"); @@ -733,7 +752,7 @@ /* Get MAC address. FIXME: read EEPROM */ for (i = 0; i < MAC_ADDR_LEN; i++) - dev->enetaddr[i] = RTL_R8(MAC0 + i); + bis->bi_enetaddr[i] = dev->enetaddr[i] = RTL_R8(MAC0 + i); #ifdef DEBUG_RTL8169 printf("MAC Address"); @@ -805,33 +824,68 @@ PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego); udelay(100); +#ifdef CONFIG_LINKSTATION +void miconCntl_FanLow(void); +void miconCntl_FanHigh(void); +void miconCntl_Eth1000M(int up); +void miconCntl_Eth100M(int up); +void miconCntl_Eth10M(int up); +void miconCntl_5f(void); + + miconCntl_FanLow(); +#endif + /* wait for auto-negotiation process */ for (i = 10000; i > 0; i--) { /* check if auto-negotiation complete */ if (mdio_read(PHY_STAT_REG) & PHY_Auto_Neco_Comp) { udelay(100); option = RTL_R8(PHYstatus); +#if defined(CONFIG_LINKSTATION) && defined(CONFIG_HTGL) if (option & _1000bpsF) { #ifdef DEBUG_RTL8169 printf("%s: 1000Mbps Full-duplex operation.\n", dev->name); #endif - } else { + miconCntl_Eth1000M(1); + } else if (option & _100bps) { +#ifdef DEBUG_RTL8169 + printf("%s: 100Mbps %s-duplexoperation.\n", + dev->name, + (option & FullDup) ? "Full" : "Half"); +#endif + miconCntl_Eth100M(1); + } else if (option & _10bps) { #ifdef DEBUG_RTL8169 printf - ("%s: %sMbps %s-duplex operation.\n", + ("%s: 10Mbps %s-duplex operation.\n", dev->name, - (option & _100bps) ? "100" : - "10", - (option & FullDup) ? "Full" : - "Half"); + (option & FullDup) ? "Full" : "Half"); +#endif + miconCntl_Eth100M(1); + } + miconCntl_5f(); +#else /* !defined(CONFIG_LINKSTATION) || !defined(CONFIG_HTGL) */ + if (option & _1000bpsF) { +#ifdef DEBUG_RTL8169 + printf("%s: 1000Mbps Full-duplex operation.\n", + dev->name); +#endif + miconCntl_FanHigh(); + } else { +#ifdef DEBUG_RTL8169 + printk("%s: %sMbps %s-duplex operation.\n", + dev->name, + (option & _100bps) ? "100" : "10", + (option & FullDup) ? "Full" : "Half"); #endif } +#endif break; } else { udelay(100); } - } /* end for-loop to wait for auto-negotiation process */ + } /* end for-loop to wait for auto-negotiation process */ } else { udelay(100); @@ -886,3 +940,5 @@ } #endif + +/* vim: set ts=4: */ diff -urN u-boot-86xx/fs/ext2/ext2fs.c u-boot-86xx-kuro_clean/fs/ext2/ext2fs.c --- u-boot-86xx/fs/ext2/ext2fs.c 2006-10-13 00:27:17.000000000 +0200 +++ u-boot-86xx-kuro_clean/fs/ext2/ext2fs.c 2006-11-06 22:05:38.000000000 +0100 @@ -35,6 +35,8 @@ /* Magic value used to identify an ext2 filesystem. */ #define EXT2_MAGIC 0xEF53 +/* Magic value used to identify Buffalo's idea of ext2 */ +#define LINKSTATION_MAGIC 0xEF54 /* Amount of indirect blocks in an inode. */ #define INDIRECT_BLOCKS 12 /* Maximum lenght of a pathname. */ @@ -851,7 +853,8 @@ goto fail; } /* Make sure this is an ext2 filesystem. */ - if (__le16_to_cpu (data->sblock.magic) != EXT2_MAGIC) { + if ((__le16_to_cpu (data->sblock.magic) != EXT2_MAGIC) && + (__le16_to_cpu (data->sblock.magic) != LINKSTATION_MAGIC)) { goto fail; } data->diropen.data = data; diff -urN u-boot-86xx/include/configs/linkstation.h u-boot-86xx-kuro_clean/include/configs/linkstation.h --- u-boot-86xx/include/configs/linkstation.h 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-86xx-kuro_clean/include/configs/linkstation.h 2006-11-06 22:30:33.000000000 +0100 @@ -0,0 +1,492 @@ +/* + * Copyright (C) 2006 Mihai Georgian + * + * 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 + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#if 0 +#define DEBUG +#endif + +/*----------------------------------------------------------------------- + * User configurable settings: + * Mandatory settings: + * CONFIG_IPADDR_LS - the IP address of the LinkStation + * CONFIG_SERVERIP_LS - the address of the server for NFS/TFTP/DHCP/BOOTP + * Optional settins: + * CONFIG_NCIP_LS - the adress of the computer running net console + * if not configured, it will be set to + * CONFIG_SERVERIP_LS + */ + +#define CONFIG_IPADDR_LS 192.168.11.150 +#define CONFIG_SERVERIP_LS 192.168.11.149 + +#if !defined(CONFIG_IPADDR_LS) || !defined(CONFIG_SERVERIP_LS) +#error Both CONFIG_IPADDR_LS and CONFIG_SERVERIP_LS must be defined +#endif + +#if !defined(CONFIG_NCIP_LS) +#define CONFIG_NCIP_LS CONFIG_SERVERIP_LS +#endif + +/*---------------------------------------------------------------------- + * DO NOT CHANGE ANYTHING BELOW, UNLESS YOU KNOW WHAT YOU ARE DOING + *---------------------------------------------------------------------*/ + +#define CONFIG_MPC8245 1 +#define CONFIG_LINKSTATION 1 + +/*--------------------------------------- + * Supported models + * + * LinkStation HDLAN /KuroBox Standard (CONFIG_HLAN) + * LinkStation old model (CONFIG_LAN) - totally untested + * LinkStation HGLAN / KuroBox HG (CONFIG_HGLAN) + * + * Models not supported yet + * TeraStatin (CONFIG_HTGL) + */ + +#if defined(CONFIG_HLAN) || defined(CONFIG_LAN) +#define CONFIG_IDENT_STRING " LinkStation / KuroBox" +#elif defined(CONFIG_HGLAN) +#define CONFIG_IDENT_STRING " LinkStation HG / KuroBox HG" +#elif defined(CONFIG_HTGL) +#define CONFIG_IDENT_STRING " TeraStation" +#else +#error No LinkStation model defined +#endif + +#define CONFIG_BOOTDELAY 10 +#define CONFIG_ZERO_BOOTDELAY_CHECK +#undef CONFIG_BOOT_RETRY_TIME + +#define CONFIG_AUTOBOOT_KEYED +#define CONFIG_AUTOBOOT_PROMPT "Boot in %02d seconds ('s' to stop)..." +#define CONFIG_AUTOBOOT_STOP_STR "s" + +#define CONFIG_COMMANDS (CFG_CMD_BDI | \ + CFG_CMD_LOADS | \ + CFG_CMD_LOADB | \ + CFG_CMD_FLASH | \ + CFG_CMD_MEMORY | \ + CFG_CMD_NET | \ + CFG_CMD_ENV | \ + CFG_CMD_IDE | \ + CFG_CMD_PCI | \ + CFG_CMD_BOOTD | \ + CFG_CMD_CONSOLE | \ + CFG_CMD_RUN | \ + CFG_CMD_ECHO | \ + CFG_CMD_DHCP | \ + CFG_CMD_PING | \ + CFG_CMD_NFS | \ + CFG_CMD_EXT2 ) +#define CONFIG_BOOTP_MASK CONFIG_BOOTP_ALL + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + +/* + * Miscellaneous configurable options + */ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ + +#define CFG_PBSIZE (CFG_CBSIZE + sizeof(CFG_PROMPT) + 16) +#define CFG_MAXARGS 16 /* Max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ +#define CFG_LOAD_ADDR 0x00800000 /* Default load address: 8 MB */ + +//#define CONFIG_BOOTCOMMAND "run nfsboot" +#define CONFIG_BOOTCOMMAND "run bootcmd1" +#define CONFIG_BOOTARGS "root=/dev/hda1" +#define CONFIG_NFSBOOTCOMMAND "bootp;run nfsargs;bootm" + +#define CFG_CONSOLE_IS_IN_ENV + +#define XMK_STR(x) #x +#define MK_STR(x) XMK_STR(x) + +#if defined(CONFIG_HLAN) || defined(CONFIG_LAN) +#define UBFILE "share/u-boot/u-boot-hd.flash.bin" +#elif defined(CONFIG_HGLAN) +#define UBFILE "share/u-boot/u-boot-hg.flash.bin" +#elif defined(CONFIG_HTGL) +#define UBFILE "share/u-boot/u-boot-ht.flash.bin" +#else +#error No LinkStation model defined +#endif + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "autoload=no\0" \ + "stdin=nc\0" \ + "stdout=nc\0" \ + "stderr=nc\0" \ + "ipaddr="MK_STR(CONFIG_IPADDR_LS)"\0" \ + "netmask=255.255.255.0\0" \ + "serverip="MK_STR(CONFIG_SERVERIP_LS)"\0" \ + "ncip="MK_STR(CONFIG_NCIP_LS)"\0" \ + "netretry=no\0" \ + "nc=setenv stdin nc;setenv stdout nc;setenv stderr nc\0" \ + "ser=setenv stdin serial;setenv stdout serial;setenv stderr serial\0" \ + "ldaddr=800000\0" \ + "hdpart=0:1\0" \ + "hdfile=boot/vmlinux.UBoot\0" \ + "hdload=echo Loading ${hdpart}:${hdfile};ext2load ide ${hdpart} ${ldaddr} ${hdfile}\0" \ + "boothd=setenv bootargs root=/dev/hda1;bootm ${ldaddr}\0" \ + "hdboot=run hdload boothd\0" \ + "flboot=setenv bootargs root=/dev/hda1;bootm ffc00000\0" \ + "emboot=setenv bootargs root=/dev/ram0;bootm ffc00000\0" \ + "nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off\0" \ + "bootretry=30\0" \ + "bootcmd1=run hdboot;run flboot\0" \ + "bootcmd2=run flboot\0" \ + "bootcmd3=run emboot\0" \ + "writeng=protect off fff70000 fff7ffff;era fff70000 fff7ffff;mw.l 800000 4e474e47 1;cp.b 800000 fff70000 4\0" \ + "writeok=protect off fff70000 fff7ffff;era fff70000 fff7ffff;mw.l 800000 4f4b4f4b 1;cp.b 800000 fff70000 4\0" \ + "ubpart=0:3\0" \ + "ubfile="UBFILE"\0" \ + "ubload=echo Loading ${ubpart}:${ubfile};ext2load ide ${ubpart} ${ldaddr} ${ubfile}\0" \ + "ubsaddr=fff00000\0" \ + "ubeaddr=fff2ffff\0" \ + "ubflash=protect off ${ubsaddr} ${ubeaddr};era ${ubsaddr} ${ubeaddr};cp.b ${ldaddr} ${ubsaddr} ${filesize};cmp.b ${ldaddr} ${ubsaddr} ${filesize}\0" \ + "upgrade=run ubload ubflash\0" + +/*----------------------------------------------------------------------- + * PCI stuff + */ +#define CONFIG_PCI +#undef CONFIG_PCI_PNP +#define CONFIG_PCI_SCAN_SHOW + +#ifndef CONFIG_PCI_PNP +/* Keep the following defines in sync with the BAT mappings */ + +#define PCI_ETH_IOADDR 0xbfff00 +#define PCI_ETH_MEMADDR 0xbffffc00 +#define PCI_IDE_IOADDR 0xbffed0 +#define PCI_IDE_MEMADDR 0xbffffb00 +#define PCI_USB0_IOADDR 0 +#define PCI_USB0_MEMADDR 0xbfffe000 +#define PCI_USB1_IOADDR 0 +#define PCI_USB1_MEMADDR 0xbfffd000 +#define PCI_USB2_IOADDR 0 +#define PCI_USB2_MEMADDR 0xbfffcf00 + +#endif + +/*----------------------------------------------------------------------- + * Ethernet stuff + */ +#define CONFIG_NET_MULTI + +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) +#define CONFIG_TULIP +#define CONFIG_TULIP_USE_IO +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) +#define CONFIG_RTL8169 +#endif + +#define CONFIG_NET_RETRY_COUNT 5 + +#define CONFIG_NETCONSOLE + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + */ +#define CFG_SDRAM_BASE 0x00000000 + +#define CFG_FLASH_BASE 0xFFC00000 +#define CFG_MONITOR_BASE TEXT_BASE + +#define CFG_RESET_ADDRESS 0xFFF00100 +#define CFG_EUMB_ADDR 0x80000000 +#define CFG_PCI_MEM_ADDR 0xB0000000 +#define CFG_MISC_REGION_ADDR 0xFE000000 + +#define CFG_MONITOR_LEN 0x00040000 /* 256 kB */ +#define CFG_MALLOC_LEN (512 << 10) /* Reserve some kB for malloc() */ + +#define CFG_MEMTEST_START 0x00100000 /* memtest works on */ +#define CFG_MEMTEST_END 0x00800000 /* 1M ... 8M in DRAM */ + +/* Maximum amount of RAM */ +#if defined(CONFIG_HLAN) || defined(CONFIG_LAN) +#define CFG_MAX_RAM_SIZE 0x04000000 /* 64MB of SDRAM */ +#elif defined(CONFIG_HGLAN) || defined(CONFIG_HTGL) +#define CFG_MAX_RAM_SIZE 0x08000000 /* 128MB of SDRAM */ +#else +#error Unknown LinkStation type +#endif + +/*----------------------------------------------------------------------- + * Change TEXT_BASE in bord/linkstation/config.mk to get a RAM build + * + * RAM based builds are for testing purposes. A Linux module, uloader.o, + * exists to load U-Boot and pass control to it + * + * Always do "make clean" after changing the build type + */ +#if CFG_MONITOR_BASE < CFG_FLASH_BASE +#define CFG_RAMBOOT +#endif + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area + */ +#if 1 /* RAM is available when the first C function is called */ +#define CFG_INIT_RAM_ADDR (CFG_SDRAM_BASE + CFG_MAX_RAM_SIZE - 0x1000) +#else +#define CFG_INIT_RAM_ADDR 0x40000000 +#endif +#define CFG_INIT_RAM_END 0x1000 +#define CFG_GBL_DATA_SIZE 128 +#define CFG_GBL_DATA_OFFSET (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) + +/*---------------------------------------------------------------------- + * Serial configuration + */ +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 57600 +#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL + +#define CFG_NS16550_REG_SIZE 1 + +#define CFG_NS16550_CLK get_bus_freq(0) + +#define CFG_NS16550_COM1 (CFG_EUMB_ADDR + 0x4600) /* Console port */ +#define CFG_NS16550_COM2 (CFG_EUMB_ADDR + 0x4500) /* AVR port */ + +/* + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + * For the detail description refer to the MPC8245 user's manual. + * + * Unless indicated otherwise, the values are + * taken from the orignal Linkstation boot code + * + * Most of the low level configuration setttings are normally used + * in cpu/mpc824x/cpu_init.c which is NOT used by this implementation. + * Low level initialisation is done in board/linkstation/early_init.S + * The values below are included for reference purpose only + */ + +/* FIXME: 32.768 MHz is the crystal frequency but */ +/* the real frequency is lower by about 0.75% */ +#define CONFIG_SYS_CLK_FREQ 32768000 +#define CFG_HZ 1000 + +/* Bit-field values for MCCR1. */ +#define CFG_ROMNAL 0 +#define CFG_ROMFAL 11 + +#define CFG_BANK0_ROW 2 /* Only bank 0 used: 13 x n x 4 */ +#define CFG_BANK1_ROW 0 +#define CFG_BANK2_ROW 0 +#define CFG_BANK3_ROW 0 +#define CFG_BANK4_ROW 0 +#define CFG_BANK5_ROW 0 +#define CFG_BANK6_ROW 0 +#define CFG_BANK7_ROW 0 + +/* Bit-field values for MCCR2. */ +#define CFG_TSWAIT 0 +#define CFG_REFINT 1400 + +/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4. */ +#define CFG_BSTOPRE 121 + +/* Bit-field values for MCCR3. */ +#define CFG_REFREC 7 + +/* Bit-field values for MCCR4. */ +#define CFG_PRETOACT 2 +#define CFG_ACTTOPRE 5 /* Original value was 2 */ +#define CFG_ACTORW 2 +#define CFG_SDMODE_CAS_LAT 2 /* For 100MHz bus. Use 3 for 133MHz */ +#define CFG_REGISTERD_TYPE_BUFFER 1 +#define CFG_EXTROM 1 /* Original setting but there is no EXTROM */ +#define CFG_REGDIMM 0 +#define CFG_DBUS_SIZE2 1 +#define CFG_SDMODE_WRAP 0 + +#define CFG_PGMAX 0x32 /* All boards use this setting. Original 0x92 */ +#define CFG_SDRAM_DSCD 0x30 + +/* Memory bank settings. + * Only bits 20-29 are actually used from these vales to set the + * start/end addresses. The upper two bits will always be 0, and the lower + * 20 bits will be 0x00000 for a start address, or 0xfffff for an end + * address. Refer to the MPC8240 book. + */ + +#define CFG_BANK0_START 0x00000000 +#define CFG_BANK0_END (CFG_MAX_RAM_SIZE - 1) +#define CFG_BANK0_ENABLE 1 +#define CFG_BANK1_START 0x3ff00000 +#define CFG_BANK1_END 0x3fffffff +#define CFG_BANK1_ENABLE 0 +#define CFG_BANK2_START 0x3ff00000 +#define CFG_BANK2_END 0x3fffffff +#define CFG_BANK2_ENABLE 0 +#define CFG_BANK3_START 0x3ff00000 +#define CFG_BANK3_END 0x3fffffff +#define CFG_BANK3_ENABLE 0 +#define CFG_BANK4_START 0x3ff00000 +#define CFG_BANK4_END 0x3fffffff +#define CFG_BANK4_ENABLE 0 +#define CFG_BANK5_START 0x3ff00000 +#define CFG_BANK5_END 0x3fffffff +#define CFG_BANK5_ENABLE 0 +#define CFG_BANK6_START 0x3ff00000 +#define CFG_BANK6_END 0x3fffffff +#define CFG_BANK6_ENABLE 0 +#define CFG_BANK7_START 0x3ff00000 +#define CFG_BANK7_END 0x3fffffff +#define CFG_BANK7_ENABLE 0 + +#define CFG_ODCR 0x95 /* 0x15 or 0x95 ? */ + +/*---------------------------------------------------------------------- + * Initial BAT mappings + */ + +/* NOTES: + * 1) GUARDED and WRITETHROUGH not allowed in IBATS + * 2) CACHEINHIBIT and WRITETHROUGH not allowed together in same BAT + */ + +/* SDRAM */ +#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_128M | BATU_VS | BATU_VP) + +#define CFG_DBAT0L CFG_IBAT0L +#define CFG_DBAT0U CFG_IBAT0U + +/* EUMB: 1MB of address space */ +#define CFG_IBAT1L (CFG_EUMB_ADDR | BATL_PP_10 | BATL_CACHEINHIBIT) +#define CFG_IBAT1U (CFG_EUMB_ADDR | BATU_BL_1M | BATU_VS | BATU_VP) + +#define CFG_DBAT1L (CFG_IBAT1L | BATL_GUARDEDSTORAGE) +#define CFG_DBAT1U CFG_IBAT1U + +/* PCI Mem: 256MB of address space */ +#define CFG_IBAT2L (CFG_PCI_MEM_ADDR | BATL_PP_10 | BATL_CACHEINHIBIT) +#define CFG_IBAT2U (CFG_PCI_MEM_ADDR | BATU_BL_256M | BATU_VS | BATU_VP) + +#define CFG_DBAT2L (CFG_IBAT2L | BATL_GUARDEDSTORAGE) +#define CFG_DBAT2U CFG_IBAT2U + +/* PCI and local ROM/Flash: last 32MB of address space */ +#define CFG_IBAT3L (CFG_MISC_REGION_ADDR | BATL_PP_10 | BATL_CACHEINHIBIT) +#define CFG_IBAT3U (CFG_MISC_REGION_ADDR | BATU_BL_32M | BATU_VS | BATU_VP) + +#define CFG_DBAT3L (CFG_IBAT3L | BATL_GUARDEDSTORAGE) +#define CFG_DBAT3U CFG_IBAT3U + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + * + * FIXME: This doesn't appear to be true for the newer kernels + * which map more that 8 MB + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ + +/*----------------------------------------------------------------------- + * FLASH organization + */ +#undef CFG_FLASH_PROTECTION +#define CFG_MAX_FLASH_BANKS 1 /* Max number of flash banks */ +#define CFG_MAX_FLASH_SECT 72 /* Max number of sectors per flash */ + +#define CFG_FLASH_ERASE_TOUT 12000 +#define CFG_FLASH_WRITE_TOUT 1000 + + +#define CFG_ENV_IS_IN_FLASH +/* + * The original LinkStation flash organisation uses + * 448 kB (0xFFF00000 - 0xFFF6FFFF) for the boot loader + * We use the last sector of this area to store the environment + * which leaves max. 384 kB for the U-Boot itself + */ +#define CFG_ENV_ADDR 0xFFF60000 +#define CFG_ENV_SIZE 0x00010000 +#define CFG_ENV_SECT_SIZE 0x00010000 + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 32 +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 5 /* log base 2 of the above value */ +#endif + +/*----------------------------------------------------------------------- + * IDE/ATA definitions + */ +#undef CONFIG_IDE_LED /* No IDE LED */ +#define CONFIG_IDE_RESET /* no reset for ide supported */ +#define CONFIG_IDE_PREINIT /* check for units */ +#define CONFIG_LBA48 /* 48 bit LBA supported */ + +#if defined(CONFIG_LAN) || defined(CONFIG_HLAN) || defined(CONFIG_HGLAN) +#define CFG_IDE_MAXBUS 1 /* Scan only 1 IDE bus */ +#define CFG_IDE_MAXDEVICE 1 /* Only 1 drive per IDE bus */ +#elif defined(CONFIG_HGTL) +#define CFG_IDE_MAXBUS 2 /* Max. 2 IDE busses */ +#define CFG_IDE_MAXDEVICE 2 /* max. 2 drives per IDE bus */ +#else +#error Config IDE: Unknown LinkStation type +#endif + +#define CFG_ATA_BASE_ADDR 0 + +#define CFG_ATA_DATA_OFFSET 0 /* Offset for data I/O */ +#define CFG_ATA_REG_OFFSET 0 /* Offset for normal registers */ +#define CFG_ATA_ALT_OFFSET 0 /* Offset for alternate registers */ + +/*----------------------------------------------------------------------- + * Partitions and file system + */ +#define CONFIG_DOS_PARTITION + +/*----------------------------------------------------------------------- + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + +#endif /* __CONFIG_H */ + +/* vim: set ts=4: */ diff -urN u-boot-86xx/include/devices.h u-boot-86xx-kuro_clean/include/devices.h --- u-boot-86xx/include/devices.h 2006-10-13 00:27:18.000000000 +0200 +++ u-boot-86xx-kuro_clean/include/devices.h 2006-11-06 22:05:38.000000000 +0100 @@ -93,6 +93,7 @@ int devices_init (void); int devices_done (void); int device_deregister(char *devname); +int console_setfile (int file, device_t * dev); #ifdef CONFIG_LCD int drv_lcd_init (void); #endif @@ -111,5 +112,8 @@ #ifdef CONFIG_NETCONSOLE int drv_nc_init (void); #endif +#if defined(CFG_CONSOLE_IS_IN_ENV) || defined(CONFIG_SPLASH_SCREEN) || defined(CONFIG_SILENT_CONSOLE) +device_t *search_device (int flags, char *name); +#endif #endif /* _DEVICES_H_ */ diff -urN u-boot-86xx/include/flash.h u-boot-86xx-kuro_clean/include/flash.h --- u-boot-86xx/include/flash.h 2006-10-13 00:27:18.000000000 +0200 +++ u-boot-86xx-kuro_clean/include/flash.h 2006-11-06 22:05:38.000000000 +0100 @@ -215,6 +215,8 @@ #define AMD_ID_LV320B_2 0x221A221A /* 2d ID word for AM29LV320MB at 0x38 */ #define AMD_ID_LV320B_3 0x22002200 /* 3d ID word for AM29LV320MB at 0x3c */ +#define AMD_ID_LV320T_2 0x221A221A /* 2d ID word for AM29LV320MT at 0x38 */ +#define AMD_ID_LV320T_3 0x22012201 /* 3d ID word for AM29LV320MT at 0x3c */ #define AMD_ID_LV640U 0x22D722D7 /* 29LV640U ID (64 M, uniform sectors) */ #define AMD_ID_LV650U 0x22D722D7 /* 29LV650U ID (64 M, uniform sectors) */ @@ -246,6 +248,8 @@ #define STM_ID_x800AB 0x005B005B /* M29W800AB ID (8M = 512K x 16 ) */ #define STM_ID_29W320DT 0x22CA22CA /* M29W320DT ID (32 M, top boot sector) */ #define STM_ID_29W320DB 0x22CB22CB /* M29W320DB ID (32 M, bottom boot sect) */ +#define STM_ID_29W324DT 0x225C225C /* M29W324DT ID (32 M, top boot sector) */ +#define STM_ID_29W324DB 0x225D225D /* M29W324DB ID (32 M, bottom boot sect) */ #define STM_ID_29W040B 0x00E300E3 /* M29W040B ID (4M = 512K x 8) */ #define FLASH_PSD4256GV 0x00E9 /* PSD4256 Flash and CPLD combination */ @@ -353,6 +357,8 @@ #define FLASH_STM800AB 0x0051 /* STM M29WF800AB ( 8M = 512K x 16 ) */ #define FLASH_STMW320DT 0x0052 /* STM M29W320DT (32 M, top boot sector) */ #define FLASH_STMW320DB 0x0053 /* STM M29W320DB (32 M, bottom boot sect)*/ +#define FLASH_STMW324DT 0x005C /* STM M29W320DT (32 M, top boot sector) */ +#define FLASH_STMW324DB 0x005D /* STM M29W320DB (32 M, bottom boot sect)*/ #define FLASH_STM320DB 0x00CB /* STM M29W320DB (4M = 64K x 64, bottom)*/ #define FLASH_STM800DT 0x00D7 /* STM M29W800DT (1M = 64K x 16, top) */ #define FLASH_STM800DB 0x005B /* STM M29W800DB (1M = 64K x 16, bottom)*/ diff -urN u-boot-86xx/include/pci_ids.h u-boot-86xx-kuro_clean/include/pci_ids.h --- u-boot-86xx/include/pci_ids.h 2006-10-13 00:27:18.000000000 +0200 +++ u-boot-86xx-kuro_clean/include/pci_ids.h 2006-11-06 22:05:38.000000000 +0100 @@ -1473,6 +1473,8 @@ #define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801 #define PCI_DEVICE_ID_ITE_IT8181 0x8181 #define PCI_DEVICE_ID_ITE_8872 0x8872 +#define PCI_DEVICE_ID_ITE_8211 0x8211 +#define PCI_DEVICE_ID_ITE_8212 0x8212 #define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886 diff -urN u-boot-86xx/lib_ppc/board.c u-boot-86xx-kuro_clean/lib_ppc/board.c --- u-boot-86xx/lib_ppc/board.c 2006-10-13 00:27:19.000000000 +0200 +++ u-boot-86xx-kuro_clean/lib_ppc/board.c 2006-11-06 22:05:38.000000000 +0100 @@ -439,6 +439,10 @@ */ addr -= len; addr &= ~(4096 - 1); +#ifdef CONFIG_LINKSTATION + /* U-Boot code at 1 MB boundary to make it easier to debug */ + addr &= ~(1048576 - 1); +#endif #ifdef CONFIG_E500 /* round down to next 64 kB limit so that IVPR stays aligned */ addr &= ~(65536 - 1); @@ -895,8 +899,10 @@ /* Initialize the jump table for applications */ jumptable_init (); +#if !defined(CONFIG_LINKSTATION) /* Initialize the console (after the relocation and devices init) */ console_init_r (); +#endif #if defined(CONFIG_CCM) || \ defined(CONFIG_COGENT) || \ @@ -949,6 +955,7 @@ if ((s = getenv ("loadaddr")) != NULL) { load_addr = simple_strtoul (s, NULL, 16); } + debug("load_addr: %08lx\n", load_addr); #if (CONFIG_COMMANDS & CFG_CMD_NET) if ((s = getenv ("bootfile")) != NULL) { copy_filename (BootFile, s, sizeof (BootFile)); @@ -998,6 +1005,11 @@ reset_phy (); #endif +#if defined(CONFIG_LINKSTATION) + /* The LinkStation uses the net console by default */ + console_init_r (); +#endif + #ifdef CONFIG_POST post_run (NULL, POST_RAM | post_bootmode_get(0)); #endif diff -urN u-boot-86xx/lib_ppc/interrupts.c u-boot-86xx-kuro_clean/lib_ppc/interrupts.c --- u-boot-86xx/lib_ppc/interrupts.c 2006-10-13 00:27:19.000000000 +0200 +++ u-boot-86xx-kuro_clean/lib_ppc/interrupts.c 2006-11-06 22:05:38.000000000 +0100 @@ -40,7 +40,7 @@ #endif extern int interrupt_init_cpu (unsigned *); -extern void timer_interrupt_cpu (struct pt_regs *); +extern void timer_interrupt_cpu (struct pt_regs *, ulong timestamp); static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */ @@ -111,7 +111,7 @@ void timer_interrupt (struct pt_regs *regs) { /* call cpu specific function from $(CPU)/interrupts.c */ - timer_interrupt_cpu (regs); + timer_interrupt_cpu (regs, timestamp); /* Restore Decrementer Count */ set_dec (decrementer_count); diff -urN u-boot-86xx/net/net.c u-boot-86xx-kuro_clean/net/net.c --- u-boot-86xx/net/net.c 2006-10-13 00:27:19.000000000 +0200 +++ u-boot-86xx-kuro_clean/net/net.c 2006-11-06 22:05:38.000000000 +0100 @@ -641,6 +641,11 @@ { uchar *pkt; +#ifdef ET_DEBUG + printf("%s dest: %08lx, dport: %d, sport: %d, len: %d\n", + __FUNCTION__, dest, dport, sport, len); +#endif + /* convert to new style broadcast */ if (dest == 0) dest = 0xFFFFFFFF; @@ -758,6 +763,8 @@ IPaddr_t tmp; volatile IP_t *ip = (volatile IP_t *)pkt; + if (!pkt && !dest && !src && !len) /* ARP packet */ + return; tmp = NetReadIP((void *)&ip->ip_src); if (tmp != NetPingIP) return; @@ -1146,7 +1153,7 @@ ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid; #ifdef ET_DEBUG - printf("packet received\n"); + printf("%s: packet received\n", __FUNCTION__); #endif NetRxPkt = inpkt; @@ -1171,10 +1178,6 @@ x = ntohs(et->et_protlen); -#ifdef ET_DEBUG - printf("packet received\n"); -#endif - if (x < 1514) { /* * Got a 802 packet. Check the other protocol field. @@ -1305,13 +1308,16 @@ /* matched waiting packet's address */ if (tmp == NetArpWaitReplyIP) { #ifdef ET_DEBUG - puts ("Got it\n"); + puts ("ARP reply IP matches original pkt IP\n"); #endif /* save address for later use */ memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6); #ifdef CONFIG_NETCONSOLE - (*packetHandler)(0,0,0,0); + if (packetHandler) + (*packetHandler)(0,0,0,0); + else + printf("ARP: NULL packetHandler\n"); #endif /* modify header, and transmit it */ memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6); @@ -1354,7 +1360,10 @@ NetCopyIP(&NetServerIP, &arp->ar_data[ 6]); memcpy (NetServerEther, &arp->ar_data[ 0], 6); - (*packetHandler)(0,0,0,0); + if (packetHandler) + (*packetHandler)(0,0,0,0); + else + printf("ARP: NULL packetHandler\n"); } break; diff -urN u-boot-86xx/net/nfs.c u-boot-86xx-kuro_clean/net/nfs.c --- u-boot-86xx/net/nfs.c 2006-10-13 00:27:19.000000000 +0200 +++ u-boot-86xx-kuro_clean/net/nfs.c 2006-11-06 22:05:38.000000000 +0100 @@ -29,7 +29,7 @@ #include "nfs.h" #include "bootp.h" -/*#define NFS_DEBUG*/ +#undef NFS_DEBUG #if ((CONFIG_COMMANDS & CFG_CMD_NET) && (CONFIG_COMMANDS & CFG_CMD_NFS)) @@ -180,6 +180,9 @@ int sport; id = ++rpc_id; +#ifdef NFS_DEBUG + printf ("%s xid: %d, rpc_id: %d\n", __FUNCTION__, id, rpc_id); +#endif pkt.u.call.id = htonl(id); pkt.u.call.type = htonl(MSG_CALL); pkt.u.call.rpcvers = htonl(2); /* use RPC version 2 */ @@ -213,6 +216,10 @@ { uint32_t data[16]; +#ifdef NFS_DEBUG + printf ("%s\n", __FUNCTION__); +#endif + data[0] = 0; data[1] = 0; /* auth credential */ data[2] = 0; data[3] = 0; /* auth verifier */ data[4] = htonl(prog); @@ -234,6 +241,10 @@ int len; int pathlen; +#ifdef NFS_DEBUG + printf ("%s\n", __FUNCTION__); +#endif + pathlen = strlen (path); p = &(data[0]); @@ -259,6 +270,10 @@ uint32_t *p; int len; +#ifdef NFS_DEBUG + printf ("%s\n", __FUNCTION__); +#endif + if ((NfsSrvMountPort == -1) || (!fs_mounted)) { /* Nothing mounted, nothing to umount */ return; @@ -286,6 +301,10 @@ uint32_t *p; int len; +#ifdef NFS_DEBUG + printf ("%s\n", __FUNCTION__); +#endif + p = &(data[0]); p = (uint32_t *)rpc_add_credentials ((long *)p); @@ -308,6 +327,10 @@ int len; int fnamelen; +#ifdef NFS_DEBUG + printf ("%s\n", __FUNCTION__); +#endif + fnamelen = strlen (fname); p = &(data[0]); @@ -335,6 +358,10 @@ uint32_t *p; int len; +#ifdef NFS_DEBUG + printf ("%s\n", __FUNCTION__); +#endif + p = &(data[0]); p = (uint32_t *)rpc_add_credentials ((long *)p); @@ -405,8 +432,13 @@ if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || - rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.astatus) { +#ifdef NFS_DEBUG + printf ("rstatus: %d\n", rpc_pkt.u.reply.rstatus); + printf ("verifier: %08lx\n", rpc_pkt.u.reply.verifier); + printf ("v2: %08lx\n", rpc_pkt.u.reply.v2); + printf ("astatus: %d\n", rpc_pkt.u.reply.astatus); +#endif return -1; } @@ -433,13 +465,24 @@ memcpy ((unsigned char *)&rpc_pkt, pkt, len); - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) + if (ntohl(rpc_pkt.u.reply.id) != rpc_id) { +#ifdef NFS_DEBUG + printf ("rpc_id error. expected: %d, got: %d\n", \ + rpc_id, ntohl(rpc_pkt.u.reply.id)); +#endif return -1; + } if (rpc_pkt.u.reply.rstatus || rpc_pkt.u.reply.verifier || rpc_pkt.u.reply.astatus || rpc_pkt.u.reply.data[0]) { +#ifdef NFS_DEBUG + printf ("rstatus: %d\n", rpc_pkt.u.reply.rstatus); + printf ("verifier: %08lx\n", rpc_pkt.u.reply.verifier); + printf ("astatus: %d\n", rpc_pkt.u.reply.astatus); + printf ("data[0]: %08lx\n", rpc_pkt.u.reply.data[0]); +#endif return -1; } @@ -544,7 +587,7 @@ struct rpc_t rpc_pkt; int rlen; -#ifdef NFS_DEBUG_nop +#ifdef NFS_DEBUG printf ("%s\n", __FUNCTION__); #endif @@ -601,6 +644,8 @@ printf ("%s\n", __FUNCTION__); #endif + if (!pkt && !dest && !src && !len) /* ARP packet */ + return; if (dest != NfsOurPort) return; switch (NfsState) { diff -urN u-boot-86xx/tools/Makefile u-boot-86xx-kuro_clean/tools/Makefile --- u-boot-86xx/tools/Makefile 2006-10-13 00:27:19.000000000 +0200 +++ u-boot-86xx-kuro_clean/tools/Makefile 2006-11-06 22:18:42.000000000 +0100 @@ -21,10 +21,10 @@ # MA 02111-1307 USA # -BIN_FILES = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX) +BIN_FILES = img2srec$(SFX) mkimage$(SFX) envcrc$(SFX) gen_eth_addr$(SFX) bmp_logo$(SFX) ncb$(SFX) OBJ_LINKS = environment.o crc32.o -OBJ_FILES = img2srec.o mkimage.o envcrc.o gen_eth_addr.o bmp_logo.o +OBJ_FILES = img2srec.o mkimage.o envcrc.o gen_eth_addr.o bmp_logo.o ncb.o ifeq ($(ARCH),mips) BIN_FILES += inca-swap-bytes$(SFX)