--- /dev/null
+
+ 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 <your_build_directory>
+ # export UBOOT_BUILD=<your_build_directory>
+ # 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
+ # . <path_to_your_ELDK>/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="" //<your_linkstation_name_or_ip>/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="" //<your_linkstation_name_or_ip>/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 <ip_of_your_linkstation>
+
+ Where <ip_of_your_linkstation> 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
--- /dev/null
+#
+# (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
+
+#########################################################################
--- /dev/null
+/*
+ * avr.c
+ *
+ * AVR functions
+ *
+ * Copyright (C) 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk>
+ *
+ * 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 <common.h>
+#include <ns16550.h>
+#include <console.h>
+
+/* 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: */
--- /dev/null
+/*
+ * 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 <u-boot@linuxnotincluded.org.uk>
+ *
+ * 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 <mporter@mvista.com>
+ * 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 <common.h>
+#include <command.h>
+
+#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: */
--- /dev/null
+#
+# (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)
--- /dev/null
+/*
+ * 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 <u-boot@linuxnotincluded.org.uk>
+ *
+ * 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 <config.h>
+#include <ppc_asm.tmpl>
+#include <mpc824x.h>
+#include <ppc_defs.h>
+#include <asm/cache.h>
+
+#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
--- /dev/null
+#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)));
+// ----------------------------------------------------
--- /dev/null
+/*
+ * flash.c
+ *
+ * Flash device interface for LinkStation
+ * Supports CFI flash devices using the AMD standard command set
+ *
+ * Copyright (C) 2006 Mihai Georgin <u-boot@linuxnotincluded.org.uk>
+ *
+ * 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 <common.h>
+#include <asm/io.h>
+#include <mpc824x.h>
+
+#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; i<info->sector_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; i<cfi->cfiq->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<<cfip->WordWriteTimeoutTyp);
+ printf("Maximum byte/word write timeout: %d us\n",
+ (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
+
+ if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
+ printf("Typical full buffer write timeout: %d us\n",
+ 1<<cfip->BufWriteTimeoutTyp);
+ printf("Maximum full buffer write timeout: %d us\n",
+ (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
+ }
+ else
+ printf("Full buffer write not supported\n");
+
+ printf("Typical block erase timeout: %d ms\n",
+ 1<<cfip->BlockEraseTimeoutTyp);
+ printf("Maximum block erase timeout: %d ms\n",
+ (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
+ if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
+ printf("Typical chip erase timeout: %d ms\n",
+ 1<<cfip->ChipEraseTimeoutTyp);
+ printf("Maximum chip erase timeout: %d ms\n",
+ (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->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; i<cfi->cfiq->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<<x)
+/*
+ * Check the flash command state
+ */
+static int flash_amdstd_state(__u32 addr, __u32 target, int timeout)
+{
+ __u32 start_time = get_timer(0);
+ __u32 data;
+
+ debug("%s\n", __FUNCTION__);
+
+ do {
+ data = cfi_read8(addr);
+ if((data & BIT(7)) == (target & BIT(7)))
+ return 0;
+ if(data & BIT(5)) {
+ data = cfi_read8(addr);
+ if((data & BIT(7)) == (target & BIT(7)))
+ return 0;
+ else
+ return -1;
+ }
+ } while (get_timer(start_time) < timeout);
+ return -1;
+}
+
+/*
+ * Verify data written to flash
+ */
+static int flash_amdstd_vrfy(flash_info_t *info, __u8 *buf, __u32 addr, int sz)
+{
+ __u32 base = cfi->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: */
--- /dev/null
+/*
+ * 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 <config.h>
+#include <common.h>
+#include <command.h>
+
+#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: */
--- /dev/null
+/*
+ * (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 <common.h>
+
+#ifdef CFG_CMD_IDE
+#include <ata.h>
+#include <ide.h>
+#include <pci.h>
+
+#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: */
--- /dev/null
+/*
+ * linkstation.c
+ *
+ * Misc LinkStation specific functions
+ *
+ * Copyright (C) 2006 Mihai Georgin <u-boot@linuxnotincluded.org.uk>
+ *
+ * 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 <version.h>
+#include <common.h>
+#include <mpc824x.h>
+#include <asm/io.h>
+#include <ns16550.h>
+
+#ifdef CONFIG_PCI
+#include <pci.h>
+#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: */
--- /dev/null
+#! /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
+
--- /dev/null
+/*
+ * (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 = .);
+}
--- /dev/null
+/*
+ * Copyright (C) 2006 Mihai Georgian <u-boot@linuxnotincluded.org.uk>
+ *
+ * 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 <cmd_confdefs.h>
+
+/*
+ * 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: */