summaryrefslogtreecommitdiffstats
path: root/arch/mips/galileo-boards
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-12-04 04:04:09 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-12-04 04:04:09 +0000
commit074da8c3f230190b4a00177ff781f0a76d8b0dfe (patch)
treef62c562c8c324258f0c79cea9b99172783212827 /arch/mips/galileo-boards
parent1fbefa026d5a271ed014b1bb730de8de06ca89d5 (diff)
EV64120 support. From Steve Johnson.
Diffstat (limited to 'arch/mips/galileo-boards')
-rw-r--r--arch/mips/galileo-boards/ev64120/Makefile27
-rw-r--r--arch/mips/galileo-boards/ev64120/cntmr.c207
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/Makefile180
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/README131
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/burner.c232
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/doit.c75
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/etherboot.h566
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c199
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/fixit17
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/flashdrv.c1560
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/galileo_port.h8
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/gt64011.h279
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/head.S19
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/ld.script.gal19
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash29
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash224
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner11
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/load.c244
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/meminit.S187
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/memory.c593
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/misc.c313
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/ns16550.h126
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/osdep.h36
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/pci.c1336
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c318
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h144
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/sbd.h52
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S1054
-rw-r--r--arch/mips/galileo-boards/ev64120/compressed/xfer.c114
-rw-r--r--arch/mips/galileo-boards/ev64120/dma.c168
-rw-r--r--arch/mips/galileo-boards/ev64120/i2o.c689
-rw-r--r--arch/mips/galileo-boards/ev64120/int-handler.S117
-rw-r--r--arch/mips/galileo-boards/ev64120/irq-handler.c274
-rw-r--r--arch/mips/galileo-boards/ev64120/irq.c488
-rw-r--r--arch/mips/galileo-boards/ev64120/ld.script.galileo113
-rw-r--r--arch/mips/galileo-boards/ev64120/pci_bios.c1266
-rw-r--r--arch/mips/galileo-boards/ev64120/promcon.c80
-rw-r--r--arch/mips/galileo-boards/ev64120/reset.c73
-rw-r--r--arch/mips/galileo-boards/ev64120/serialGT.c212
-rw-r--r--arch/mips/galileo-boards/ev64120/setup.c234
40 files changed, 11814 insertions, 0 deletions
diff --git a/arch/mips/galileo-boards/ev64120/Makefile b/arch/mips/galileo-boards/ev64120/Makefile
new file mode 100644
index 000000000..af08f9dcd
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/Makefile
@@ -0,0 +1,27 @@
+#
+# Copyright 2000 RidgeRun, Inc.
+# Author: RidgeRun, Inc.
+# glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+#
+# Makefile for the Galileo EV64120 board.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+all: ev64120.o
+O_TARGET := ev64120.o
+O_OBJS := serialGT.o int-handler.o promcon.o reset.o setup.o irq.o irq-handler.o i2o.o pci_bios.o
+
+int-handler.o: int-handler.S
+
+clean:
+ *.o
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/mips/galileo-boards/ev64120/cntmr.c b/arch/mips/galileo-boards/ev64120/cntmr.c
new file mode 100644
index 000000000..568a88cb0
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/cntmr.c
@@ -0,0 +1,207 @@
+/* cntmr.c - GT counters/timers functions */
+
+/* Copyright - Galileo technology. 9/3/2000 */
+
+/*
+DESCRIPTION
+This file contains function which serves the user with a complete interface
+to the GT internal counters and timers, please advise: each counter/timer unit
+can function only as a counter or a timer at current time.
+Counter/timer 0 is 32 bit wide.
+Counters/timers 1-3 are 24 bit wide.
+*/
+
+/* includes */
+
+#ifdef __linux__
+#include <asm/galileo/evb64120A/cntmr.h>
+#include <asm/galileo/evb64120A/core.h>
+#else
+#include "cntmr.h"
+#include "core.h"
+#endif
+
+/********************************************************************
+* cntTmrStart - Starts a counter/timer with given an initiate value.
+*
+* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers.
+* unsigned int countValue - Initial value for count down.
+* CNT_TMR_OP_MODES opMode - Set Mode, Counter or Timer.
+*
+* RETURNS: false if one of the parameters is erroneous, true otherwise.
+*********************************************************************/
+
+bool cntTmrStart(CNTMR_NUM countNum, unsigned int countValue,
+ CNT_TMR_OP_MODES opMode)
+{
+ unsigned int command = 1;
+ unsigned int value;
+
+ if (countNum > LAST_CNTMR)
+ return false;
+ else {
+ GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+ cntTmrDisable(countNum);
+ GT_REG_WRITE((TIMER_COUNTER0 + (4 * countNum)),
+ countValue);
+ command = command << countNum * 2;
+ value = value | command;
+ command = command << 1;
+ switch (opMode) {
+ case TIMER: /* The Timer/Counter bit set to logic '1' */
+ value = value | command;
+ break;
+ case COUNTER: /* The Timer/Counter bit set to logic '0' */
+ value = value & ~command;
+ break;
+ default:
+ return false;
+ }
+ GT_REG_WRITE(TIMER_COUNTER_CONTROL, value);
+ return true;
+ }
+}
+
+/********************************************************************
+* cntTmrDisable - Disables the timer/counter operation and return its
+* value.
+*
+* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers.
+* RETURNS: The counter/timer value (unsigned int), if any of the arguments are
+* erroneous return 0.
+*********************************************************************/
+
+unsigned int cntTmrDisable(CNTMR_NUM countNum)
+{
+ unsigned int command = 1;
+ unsigned int regValue;
+ unsigned int value;
+
+ GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+ if (countNum > LAST_CNTMR)
+ return 0;
+ GT_REG_READ(TIMER_COUNTER0 + 4 * countNum, &regValue);
+ command = command << countNum * 2; /* Disable the timer/counter */
+ value = value & ~command;
+ GT_REG_WRITE(TIMER_COUNTER_CONTROL, value);
+ return regValue;
+}
+
+/********************************************************************
+* cntTmrRead - Reads a timer or a counter value. (This operation can be
+* perform while the counter/timer is active).
+*
+* RETURNS: The counter/timer value. If wrong input value, return 0.
+*********************************************************************/
+
+unsigned int cntTmrRead(CNTMR_NUM countNum)
+{
+ unsigned int value;
+ if (countNum > LAST_CNTMR)
+ return 0;
+ else
+ GT_REG_READ(TIMER_COUNTER0 + countNum * 4, &value);
+ return value;
+}
+
+/********************************************************************
+* cntTmrEnable - Set enable-bit of timer/counter.
+* Be aware: If the counter/timer is active, this function
+* will terminate with an false.
+*
+* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers.
+* RETURNS: false if one of the parameters is erroneous, true otherwise.
+*********************************************************************/
+
+bool cntTmrEnable(CNTMR_NUM countNum)
+{
+ unsigned int command = 1;
+ unsigned int value;
+ GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+ if (countNum > LAST_CNTMR)
+ return false;
+ else {
+ command = command << countNum * 2;
+ if ((command & value) != 0) /* ==> The counter/timer is enabled */
+ return false; /* doesn't make sense to Enable an "enabled" counter */
+ value = value | command;
+ GT_REG_WRITE(TIMER_COUNTER_CONTROL, value);
+ return true;
+ }
+}
+
+/********************************************************************
+* cntTmrLoad - loading value for timer number countNum.
+* Be aware: If this function try to load value to an enabled
+* counter/timer it terminate with false.
+*
+* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers.
+* unsigned int countValue - The value for load the register.
+* RETURNS: false if one of the parameters is erroneous, true otherwise.
+*********************************************************************/
+
+bool cntTmrLoad(unsigned int countNum, unsigned int countValue)
+{
+ unsigned int command = 1;
+ unsigned int value;
+ GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+ if (countNum > LAST_CNTMR)
+ return false;
+ else {
+ command = command << countNum * 2;
+ value = value & command;
+ if (value != 0) { /* ==> The counter/timer is enabled */
+ return false; /* can't reload value when counter/timer is enabled */
+ } else {
+ GT_REG_WRITE((TIMER_COUNTER0 + (4 * countNum)),
+ countValue);
+ return true;
+ }
+
+ }
+}
+
+/********************************************************************
+* cntTmrSetMode - Configurate the Mode of the channel to work as a counter
+* or as a timer. (for more details on the different between
+* those two modes is written in the Data Sheet).
+* NOTE: This function only set the counter/timer mode and
+* don't enable it.
+* Be aware: If this function try to load value to an enabled
+* counter/timer it terminate with false.
+*
+* INPUTS: unsigned int countNum - Selects one of the 8 counters/timers.
+* CNT_TMR_OP_MODES opMode - TIMER or COUNTER mode.
+* RETURNS: false if one of the parameters is erroneous true otherwise .
+*********************************************************************/
+
+bool cntTmrSetMode(CNTMR_NUM countNum, CNT_TMR_OP_MODES opMode)
+{
+ unsigned int command = 1;
+ unsigned int value;
+
+ GT_REG_READ(TIMER_COUNTER_CONTROL, &value);
+ if (countNum > LAST_CNTMR)
+ return false;
+ else {
+ command = command << countNum * 2;
+ value = value & command;
+ if (value != 0) { /* ==> The counter/timer is enabled */
+ return false; /* can't set the Mode when counter/timer is enabled */
+ } else {
+ command = command << 1;
+ switch (opMode) {
+ case TIMER:
+ value = value | command; /* The Timer/Counter bit set to logic '1' */
+ break;
+ case COUNTER:
+ value = value & ~command; /*The Timer/Counter bit set to logic '0' */
+ break;
+ default:
+ return false;
+ }
+ GT_REG_WRITE(TIMER_COUNTER_CONTROL, value);
+ return true;
+ }
+ }
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/Makefile b/arch/mips/galileo-boards/ev64120/compressed/Makefile
new file mode 100644
index 000000000..1390af515
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/Makefile
@@ -0,0 +1,180 @@
+# =============================================================
+#
+# linux/arch/mips/galileo/compressed/Makefile
+#
+# By RidgeRun Inc.
+#
+# Description:
+# Create a system containing a copy of the compressed vmlinux kernel.
+# The system knows how to decompress the contained kernel and then
+# jump to it resulting in a linux kernel boot.
+#
+# The system comes in three forms:
+#
+# 1. - ramsys -
+# to be loaded into ram then run. When run
+# it decompresses the kernel housed in its internal
+# data structures and then jumps to the image which
+# results in a linux kernel boot.
+#
+# 2. - flashsys -
+# to be loaded into ram so that it can be
+# burned into the onboard flash. Then the board jumpers
+# can be switched so that the next power cycle caused
+# the system in flash to run which then proceeds as
+# described by #1 above.
+# Note: burner.srec is the utility that will allow
+# the user to get this image into flash.
+#
+# 3. - flashsys2 -
+# to be loaded into ram so that it can be
+# burned into the onboard flash. Then on each power
+# cycle when the standard PMON prompt is presented
+# the user can type `call 0xbf000000` to invoke
+# the system in flash which then proceeds as
+# described by #1 above.
+# Note: burner.srec is the utility that will allow
+# the user to get this image into flash.
+#
+# 4. - burner.srec -
+# related to #2 and #3 above.
+#
+# =============================================================
+
+all: ramsys.srec \
+ flashsys.srec \
+ flashsys2.srec \
+ burner.srec
+
+SYSTEM = $(TOPDIR)/vmlinux
+
+CFLAGS_2 = -DCONSOLE_SERIAL -DDELIMITERLINES -DGALILEO_PORT \
+ -DANSIESC -DELF_IMAGE -DELF_IMAGE -DDOWNLOAD_PROTO_TFTP \
+ -DEVB64120A -D__MIPSEB__ -DINCLUDE_EEPRO100 \
+ -DINCLUDE_GETH0 -DNOPRINTK -DPROM -DCOMPRESSEDVMLINUX
+
+sbdreset_evb64120A.o:
+ $(CC) $(CFLAGS) $(CFLAGS_2) -c sbdreset_evb64120A.S -o $*.o
+memory.o:
+ $(CC) $(CFLAGS) $(CFLAGS_2) -c memory.c -o $*.o
+pci.o:
+ $(CC) $(CFLAGS) $(CFLAGS_2) -c pci.c -o $*.o
+pci_etherboot.o:
+ $(CC) $(CFLAGS) $(CFLAGS_2) -c pci_etherboot.c -o $*.o
+load.o:
+ $(CC) $(CFLAGS) $(CFLAGS_2) -c load.c -o $*.o
+flashdrv.o:
+ $(CC) $(CFLAGS) $(CFLAGS_2) -c flashdrv.c -o $*.o
+
+.S.s:
+ $(CPP) $(CFLAGS) $< -o $*.s
+.S.o:
+ $(CC) $(CFLAGS) -c $< -o $*.o
+
+gz2asm: gz2asm.c
+ g++ -o gz2asm gz2asm.c
+
+doit: doit.c
+ gcc -o doit doit.c
+
+piggy.gz: $(SYSTEM)
+ rm -f piggy piggy.gz
+ $(OBJCOPY) -S -O binary $(SYSTEM) piggy
+ gzip -f -9 < piggy > piggy.gz
+
+piggy.S: doit fixit piggy.gz
+ ./doit < piggy.gz > piggy.S; . ./fixit piggy.S
+
+OBJECTS_ramsys = head.o misc.o piggy.o ../serialGT.o
+OBJECTS_flashsys = sbdreset_evb64120A.o evb64120A_Setup.o pci_etherboot.o memory.o pci.o head.o misc.o piggy.o ../serialGT.o
+OBJECTS_flashsys2 = xfer.o head.o misc.o piggy.o ../serialGT.o
+OBJECTS_burner = burner.o load.o flashdrv.o
+
+ramsys.srec : $(OBJECTS_ramsys) ld.script.gal
+ @# Note: this image is intended to run out of ram. No flash involved.
+ $(LD) -T ld.script.gal -o ramsys $(OBJECTS_ramsys)
+ $(NM) ramsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_ramsys.map
+ $(OBJCOPY) -O srec ramsys ramsys.srec
+ cp ramsys.srec $(TOPDIR)/.
+
+flashsys.srec : $(OBJECTS_flashsys) ld.sys.big.Flash
+ @# Note1: Use the burn utility to get this image into flash.
+ @# Note2: This image is intended to run out of flash as invoked
+ @# directly at powerup when EVB64120A jumpers are configured to
+ @# bypass the onboard eprom.
+ @# Assumes that 0xBFC00000 is the bootup run address (normal MIPS).
+ @# And assumes that EVB64120A jumber J11 is added to the board and jumber
+ @# J20 is moved from the 2&3 position to the 1&2 position instead. Without
+ @# the jumper settings the system will execute at address 0xBFC00000,
+ @# as normal, yet that address will map to the onboard eeprom instead
+ @# of the onboard flash.
+ @#
+ $(LD) -T ld.sys.big.Flash -o flashsys $(OBJECTS_flashsys)
+ $(NM) flashsys | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys.map
+ @#
+ @# Next, Create the image that we want to place in the flash part.
+ $(OBJCOPY) -S -g --strip-unneeded \
+ --adjust-section-vma=.text+0x3f820000 \
+ --adjust-section-vma=.rodata+0x3f820000 \
+ --adjust-section-vma=.reginfo+0x3f820000 \
+ --adjust-section-vma=.data+0x3f820000 \
+ --remove-section=.bss \
+ --remove-section=.scommon \
+ --remove-section=.note \
+ --remove-section=.comment \
+ flashsys flashsys.temp
+ @#
+ @# Next, change the addresses so that when we download to
+ @# to the board's ram it will land starting at address 0xA0300000
+ @# because this is where we have choosen to have the image temporarily sit
+ @# while we subsequently burn it (using some method not revealed here) into
+ @# the board's flash. After the burn the system can be setup (via jumpers)
+ @# to boot this image directory from the flash part.
+ $(OBJCOPY) -O srec --adjust-vma=0xe0700000 flashsys.temp flashsys.srec
+ cp flashsys.srec $(TOPDIR)/.
+
+flashsys2.srec : $(OBJECTS_flashsys2) ld.sys.big.Flash2
+ @# Note1: Use the burn utility to get this image into flash.
+ @# Note2: This image is intended to be run out of flash as invoked
+ @# manually from the standard PMON running in eprom. This means that
+ @# the image will be set to run from location 0xBF000000 which is the
+ @# location the flash is mapped to when the board jumpers are set to
+ @# the standard location such that the board boots out of onboard
+ @# eprom. From the PMON prompt the user can type `call 0xbf000000`
+ @# to transfer control to the image we are constructing here.
+ @#
+ $(LD) -T ld.sys.big.Flash2 -o flashsys2 $(OBJECTS_flashsys2)
+ $(NM) flashsys2 | grep -v '\(compiled\)\|\(\.o$$\)\|\( a \)' | sort > System_flashsys2.map
+ @#
+ @# Next, Create the image that we want to place in the flash part.
+ $(OBJCOPY) -S -g --strip-unneeded \
+ --adjust-section-vma=.text+0x3ec20000 \
+ --adjust-section-vma=.rodata+0x3ec20000 \
+ --adjust-section-vma=.reginfo+0x3ec20000 \
+ --adjust-section-vma=.data+0x3ec20000 \
+ --remove-section=.bss \
+ --remove-section=.scommon \
+ --remove-section=.note \
+ --remove-section=.comment \
+ flashsys2 flashsys2.temp
+ @#
+ @# Next, change the addresses so that when we download to
+ @# to the board's ram it will land starting at address 0xA0300000
+ @# because this is where we have choosen to have the image temporarily sit
+ @# while we subsequently burn it (using some method not revealed here) into
+ @# the board's flash. After the burn a user will then be able to type
+ @# `call 0xbf000000` at the PMON prompt (following a power cycle) to invoke
+ @# the linux kernel.
+ $(OBJCOPY) -O srec --adjust-vma=0xe1300000 flashsys2.temp flashsys2.srec
+ cp flashsys2.srec $(TOPDIR)/.
+
+burner.srec : $(OBJECTS_burner) ld.sys.big.burner
+ @# This utility can be used to burn the flashsys.srec or flashsys2.srec
+ @# into the EVB64120A's on board flash part (1Meg minimum).
+ $(LD) -T ld.sys.big.burner -o burner $(OBJECTS_burner)
+ $(NM) burner | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System_burner.map
+ $(OBJCOPY) -O srec burner burner.srec
+ cp burner.srec $(TOPDIR)/.
+
+clean:
+ rm -f doit piggy.S piggy.gz piggy burner *.o ramsys* flashsys* System*.map *.srec
diff --git a/arch/mips/galileo-boards/ev64120/compressed/README b/arch/mips/galileo-boards/ev64120/compressed/README
new file mode 100644
index 000000000..2edd146d1
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/README
@@ -0,0 +1,131 @@
++------------------------------------------------+
+| $TOPDIR/arch/mips/galileo/compressed/README |
+| |
+| By RidgeRun Inc, |
+| Aug, 2000 |
++------------------------------------------------+
+
+Description:
+============
+ It is intended that this makefile be wired in to run as
+ part of a top level linux build. For example, at the
+ time of this writing, if the user types "make gboot" at
+ the top level then in addition to building vmlinux the
+ build system's makefiles will descend into this
+ directory and build the "all:" target of this
+ Makefile. This will have the result of compressing the
+ vmlinux system and producing four separate systems. The
+ following snippet is pulled from this directory's
+ Makefile and describes each system.
+
+ Four systems are availalbe for download to the EVB64120A
+ board.
+
+ 1. - ramsys -
+ To be loaded into ram then run. When run
+ it decompresses the "vmlinux" kernel housed in its internal
+ data structures and then jumps to the image which
+ results in a linux kernel boot.
+
+ 2. - flashsys -
+ To be loaded into ram so that it can be
+ burned into the onboard flash. Then the board jumpers
+ can be switched so that the next power cycle caused
+ the system in flash to run which then proceeds as
+ described by #1 above.
+ Note: burner.srec is the utility that will allow
+ the user to get this image into flash.
+
+ 3. - flashsys2 -
+ To be loaded into ram so that it can be
+ burned into the onboard flash. Then on each power
+ cycle when the standard PMON prompt is presented
+ the user can type `call 0xbf000000` to invoke
+ the system in flash which then proceeds as
+ described by #1 above.
+ Note: burner.srec is the utility that will allow
+ the user to get this image into flash.
+
+ 4. - burner.srec -
+ Related to #2 and #3 above.
+
+Example: Running from Ram
+==========================
+
+ In this scenario the compressed system is downloaded
+ into ram and run directly from there. No flash is involved
+ in this scenario. Naturally, the download must be repeated
+ on every power cycle.
+
+ 1. At the PMON prompt type `load`
+ 2. Assuming you have your host connected to /dev/ttyS0
+ type the following command in a host shell window.
+ `cat ramsys.srec > /dev/ttyS0`
+ 3. When the download completes type the following
+ at the PMON prompt: `g`
+
+
+Example: Running from flash: Scenario #1
+========================================
+
+ In this scenario vmlinux runs out of flash code
+ automatically on every power up. This means that
+ standard PMON code (of eprom) never runs.
+
+ 1. Place the boot jumpers in the Boot-from-eprom
+ state. This is the normal state and how the jumpers
+ are found when booting PMON.
+
+ Jumper settings. J11 - Removed
+ J20 - Moved from the 1&2 position to
+ the 2&3 position instead
+
+ 2. Use PMON to "load" the burner.srec image and then
+ run it. This utility will prompt you to download
+ the image that you want burned into the flash
+ part.
+
+ 3. Send the flashsys.srec image to the running burner
+ utility. The utililty will indicate when the burn
+ process has completed.
+
+ 4. Now switch off power and change the jumpers to
+ the boot-from-flash position. The next power cycle
+ will run the flash based system automatically.
+
+ Jumper settings. J11 - Added.
+ J20 - Moved from the 2&3 position to
+ the 1&2 position instead
+
+Example: Running from flash: Scenario #2
+========================================
+
+ In this scenario vmlinux runs out of flash only if the
+ PMON user decides to jump there by issuing a command to
+ PMON. Every power cycle would continue to bring up PMON
+ and a user will have to reissue the jump command to
+ force control transfer to the flash system.
+
+ 1. Insure that the boot jumpers are in the Boot-from-eprom
+ state. This is the normal state and how the jumpers
+ are found when booting PMON.
+
+ Jumper settings. J11 - Removed
+ J20 - Moved from the 1&2 position to
+ the 2&3 position instead
+
+ 2. Use PMON to "load" the burner.srec image and then
+ run it. This utility will prompt you to download
+ the image that you want burned into the flash
+ part.
+
+ 3. Send the flashsys2.srec image to the running burner
+ utility. The utililty will indicate when the burn
+ process has completed.
+
+ 4. Now that the image is in flash the user can invoke
+ the following PMON command whenever a vmlinux
+ boot is desired:
+
+ call 0xbf000000
+
diff --git a/arch/mips/galileo-boards/ev64120/compressed/burner.c b/arch/mips/galileo-boards/ev64120/compressed/burner.c
new file mode 100644
index 000000000..0a2147c5c
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/burner.c
@@ -0,0 +1,232 @@
+/*
+ * arch/mips/galileo/compressed/burner.c
+ *
+ * By RidgeRun Inc (Leveraged from Galileo's main.c, misc.c, etc).
+ *
+ * Burn image from ram to flash
+ * For use with Galileo EVB64120A MIPS eval board.
+ */
+
+#include <linux/config.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <asm/galileo-boards/evb64120A/eeprom_param.h>
+#include <asm/galileo-boards/evb64120A/flashdrv.h>
+
+#define IMAGEOFFSET 0x00300000
+
+static void burn_image_from_memory(void);
+static char *sprintf(char *buf, const char *fmt, ...);
+static void printf(const char *fmt, ...);
+
+unsigned int FlashSize;
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+int main(void)
+{
+ printf("\n");
+ printf("\n");
+ printf("\n");
+ printf("\n");
+ printf(" +--------------------+\n");
+ printf(" | |\n");
+ printf(" | Flash Burn Utility |\n");
+ printf(" | |\n");
+ printf(" +--------------------+\n");
+ printf("\n");
+ printf("Please send your *.srec image to the parallel port\n");
+ printf("\n");
+ printf("Note: The *.srec image should be setup to\n");
+ printf(" load into address 0xa0300000 where\n");
+ printf(" it will then be transferred to flash\n");
+ printf("\n");
+
+ SET_REG_BITS(0x468, BIT20); // Set Flash to be 16 bit wide
+ FlashSize = flashInit(0xbf000000, 2, X16);
+
+ galileo_dl(); // read in the users *.srec image.
+ burn_image_from_memory(); // put it in flash.
+
+ printf("\n");
+ printf("\n");
+ printf("+---------------+\n");
+ printf("| Done |\n");
+ printf("|(please reboot)|\n");
+ printf("+---------------+\n");
+ printf("\n");
+
+ while (1) {
+ }
+ return 0;
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static void burn_image_from_memory(void)
+{
+ unsigned int count, delta, temp, temp1;
+ unsigned int to_sector, last_sector;
+
+ /* Find how many sectors needed to be erased */
+ to_sector = flashInWhichSector(FlashSize - 4); // skranz, modified.
+ if (to_sector == 0xffffffff) {
+ printf
+ ("Flash Burning Error - Flash too small - Cannot burn image\n"); // skranz, modified.
+ return;
+ }
+
+ /* Which is the last sector */
+ last_sector = flashInWhichSector(FlashSize - 4);
+ delta = 0;
+ printf("\nErasing first %d sectors\n", to_sector);
+ for (count = 0; count < to_sector + 1; count++) {
+ printf("Erasing sector %d\n", count);
+ flashEraseSector(count);
+ }
+ printf("flash region size = %d\n", FlashSize); // skranz, added
+ printf("Sdram IMAGEOFFSET = %d\n", IMAGEOFFSET); // skranz, added
+
+ printf("Burning from Sdram to %d mark; full burn.\n", FlashSize);
+ for (count = 0; count < (FlashSize - delta); count = count + 4) {
+ flashWriteWord(count,
+ *(unsigned int *) ((count | NONE_CACHEABLE)
+ + IMAGEOFFSET)); // skranz, modified.
+ temp = flashReadWord(count);
+ temp1 = *(unsigned int *) ((count | NONE_CACHEABLE) + IMAGEOFFSET); // skranz, modified.
+ if (((unsigned int) temp) != ((unsigned int) temp1)) {
+ printf
+ ("Burning error at address %X : flash(%X) sdram(%X)\n",
+ count, flashReadWord(count),
+ *(unsigned int *) ((count | NONE_CACHEABLE) + IMAGEOFFSET)); // skranz, modified.
+ printf("Aborting Prematurally.\n");
+ break;
+ }
+ }
+ printf("Finished burning Image\n");
+}
+
+/******************************
+ Routine:
+ Description:
+ Formats:
+ %X - 4 byte ASCII (8 hex digits)
+ %x - 2 byte ASCII (4 hex digits)
+ %b - 1 byte ASCII (2 hex digits)
+ %d - decimal (also %i)
+ %c - ASCII char
+ %s - ASCII string
+ %I - Internet address in x.x.x.x notation
+ ******************************/
+static char hex[] = "0123456789ABCDEF";
+static char *do_printf(char *buf, const char *fmt, const int *dp)
+{
+ register char *p;
+ char tmp[16];
+ while (*fmt) {
+ if (*fmt == '%') { /* switch() uses more space */
+ fmt++;
+
+ if (*fmt == 'X') {
+ const long *lp = (const long *) dp;
+ register long h = *lp++;
+ dp = (const int *) lp;
+ *(buf++) = hex[(h >> 28) & 0x0F];
+ *(buf++) = hex[(h >> 24) & 0x0F];
+ *(buf++) = hex[(h >> 20) & 0x0F];
+ *(buf++) = hex[(h >> 16) & 0x0F];
+ *(buf++) = hex[(h >> 12) & 0x0F];
+ *(buf++) = hex[(h >> 8) & 0x0F];
+ *(buf++) = hex[(h >> 4) & 0x0F];
+ *(buf++) = hex[h & 0x0F];
+ }
+ if (*fmt == 'x') {
+ register int h = *(dp++);
+ *(buf++) = hex[(h >> 12) & 0x0F];
+ *(buf++) = hex[(h >> 8) & 0x0F];
+ *(buf++) = hex[(h >> 4) & 0x0F];
+ *(buf++) = hex[h & 0x0F];
+ }
+ if (*fmt == 'b') {
+ register int h = *(dp++);
+ *(buf++) = hex[(h >> 4) & 0x0F];
+ *(buf++) = hex[h & 0x0F];
+ }
+ if ((*fmt == 'd') || (*fmt == 'i')) {
+ register int dec = *(dp++);
+ p = tmp;
+ if (dec < 0) {
+ *(buf++) = '-';
+ dec = -dec;
+ }
+ do {
+ *(p++) = '0' + (dec % 10);
+ dec = dec / 10;
+ } while (dec);
+ while ((--p) >= tmp)
+ *(buf++) = *p;
+ }
+ if (*fmt == 'I') {
+ union {
+ long l;
+ unsigned char c[4];
+ } u;
+ const long *lp = (const long *) dp;
+ u.l = *lp++;
+ dp = (const int *) lp;
+ buf = sprintf(buf, "%d.%d.%d.%d",
+ u.c[0], u.c[1], u.c[2],
+ u.c[3]);
+ }
+ if (*fmt == 'c')
+ *(buf++) = *(dp++);
+ if (*fmt == 's') {
+ p = (char *) *dp++;
+ while (*p)
+ *(buf++) = *p++;
+ }
+ } else
+ *(buf++) = *fmt;
+ fmt++;
+ }
+ *buf = 0;
+ return (buf);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static char *sprintf(char *buf, const char *fmt, ...)
+{
+ return do_printf(buf, fmt, ((const int *) &fmt) + 1);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void putchar(int c)
+{
+ if (c == '\n') {
+ serial_putc('\r');
+ }
+ serial_putc(c);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static void printf(const char *fmt, ...)
+{
+ char buf[256], *p;
+ p = buf;
+ do_printf(buf, fmt, ((const int *) &fmt) + 1);
+ while (*p)
+ putchar(*p++);
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/doit.c b/arch/mips/galileo-boards/ev64120/compressed/doit.c
new file mode 100644
index 000000000..7986caae9
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/doit.c
@@ -0,0 +1,75 @@
+/*
+ * By RidgeRun Inc.
+ *
+ * The input to this program is intended to be
+ * a compressed linux kernel. The output of this
+ * program is then a constructed *.S file which
+ * defines a large data structure -- the contents
+ * of which represent the compressed kernel which
+ * can subsequently be used in a program designed
+ * to access that struture for decompression at
+ * runtime and then subsequent kernel bootup.
+ *
+ * Example Usage:
+ * ./doit < piggy.gz > piggy.S
+ *
+ */
+
+#include <stdio.h>
+
+void printval(int i)
+{
+ int tth, th, h, t, d;
+
+ if (i > 99999) {
+ printf("Error - printval outofbounds\n");
+ return;
+ }
+
+ tth = 0;
+ th = 0;
+ //tth = (i) / 10000;
+ //th = (i - (tth * 10000)) / 1000;
+ h = (i - ((tth * 10000) + (th * 1000))) / 100;
+ t = (i - ((tth * 10000) + (th * 1000) + (h * 100))) / 10;
+ d = (i - ((tth * 10000) + (th * 1000) + (h * 100) + (t * 10)));
+ //putchar(tth + '0');
+ //putchar(th + '0');
+ putchar(h + '0');
+ putchar(t + '0');
+ putchar(d + '0');
+}
+
+main(int argc, char **argv)
+{
+ int val;
+ int size = 0;
+ unsigned char c;
+
+ printf("gcc2_compiled.:\n");
+ printf("__gnu_compiled_c:\n");
+ printf("\t.globl linux_compressed_start\n");
+ printf("\t.text\n");
+ printf("\t.align 2\n");
+ printf("\t.type linux_compressed_start,@object\n");
+ printf("linux_compressed_start:\n");
+
+
+ val = getchar();
+ while (val != EOF) {
+ size++;
+ c = (unsigned char) (val & 0x00ff);
+ printf("\t.byte ");
+ printval((int) c);
+ printf("\n");
+ val = getchar();
+ }
+ printf("\t.size linux_compressed_start,%d\n", size);
+ printf("\t.globl linux_compressed_size\n");
+ printf("\t.text\n");
+ printf("\t.align 2\n");
+ printf("\t.type linux_compressed_size,@object\n");
+ printf("\t.size linux_compressed_size,4\n");
+ printf("linux_compressed_size:\n");
+ printf("\t.word %d\n", size);
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/etherboot.h b/arch/mips/galileo-boards/ev64120/compressed/etherboot.h
new file mode 100644
index 000000000..fd6eff847
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/etherboot.h
@@ -0,0 +1,566 @@
+/**************************************************************************
+ETHERBOOT - BOOTP/TFTP Bootstrap Program
+
+Author: Martin Renters
+ Date: Dec/93
+
+**************************************************************************/
+
+#include "osdep.h"
+
+/* These could be customised for different languages perhaps */
+#define ASK_PROMPT "Boot from (N)etwork or from (L)ocal? "
+#define ANS_NETWORK 'N'
+#define ANS_LOCAL 'L'
+#ifndef ANS_DEFAULT /* in case left out in Makefile */
+#define ANS_DEFAULT ANS_NETWORK
+#endif
+
+#define TAGGED_IMAGE /* eventually optional */
+#if !defined(TAGGED_IMAGE) && !defined(AOUT_IMAGE) && !defined(ELF_IMAGE)
+#define TAGGED_IMAGE /* choose at least one */
+#endif
+
+#define ESC 0x1B
+
+#ifndef DEFAULT_BOOTFILE
+#define DEFAULT_BOOTFILE "/tftpboot/kernel"
+#endif
+
+/* Clean up console settings... mainly CONSOLE_CRT and CONSOLE_SERIAL are used
+ * in the sources (except start.S and serial.S which cannot include
+ * etherboot.h). At least one of the CONSOLE_xxx has to be set, and
+ * CONSOLE_DUAL sets both CONSOLE_CRT and CONSOLE_SERIAL. If none is set,
+ * CONSOLE_CRT is assumed. */
+#ifdef CONSOLE_DUAL
+#undef CONSOLE_CRT
+#define CONSOLE_CRT
+#undef CONSOLE_SERIAL
+#define CONSOLE_SERIAL
+#endif
+#if defined(CONSOLE_CRT) && defined(CONSOLE_SERIAL)
+#undef CONSOLE_DUAL
+#define CONSOLE_DUAL
+#endif
+#if !defined(CONSOLE_CRT) && !defined(CONSOLE_SERIAL)
+#define CONSOLE_CRT
+#endif
+
+#ifndef DOWNLOAD_PROTO_NFS
+#undef DOWNLOAD_PROTO_TFTP
+#define DOWNLOAD_PROTO_TFTP /* default booting protocol */
+#endif
+
+#ifdef DOWNLOAD_PROTO_TFTP
+#define download(fname,loader) tftp((fname),(loader))
+#endif
+#ifdef DOWNLOAD_PROTO_NFS
+#define download(fname,loader) nfs((fname),(loader))
+#endif
+
+#ifndef MAX_TFTP_RETRIES
+#define MAX_TFTP_RETRIES 20
+#endif
+
+#ifndef MAX_BOOTP_RETRIES
+#define MAX_BOOTP_RETRIES 20
+#endif
+
+#ifndef MAX_BOOTP_EXTLEN
+#if (RELOC < 0x94000)
+/* Force internal buffer (if external buffer would overlap with our code...) */
+#undef INTERNAL_BOOTP_DATA
+#define INTERNAL_BOOTP_DATA
+#endif
+/* sizeof(struct bootp_t) == 0x240 */
+#if defined(INTERNAL_BOOTP_DATA) || (RELOC >= 0x94240)
+#define MAX_BOOTP_EXTLEN 1024
+#else
+#define MAX_BOOTP_EXTLEN (1024-sizeof(struct bootp_t))
+#endif
+#endif
+
+#ifndef MAX_ARP_RETRIES
+#define MAX_ARP_RETRIES 20
+#endif
+
+#ifndef MAX_RPC_RETRIES
+#define MAX_RPC_RETRIES 20
+#endif
+
+#define TICKS_PER_SEC 18
+
+/* Inter-packet retry in ticks */
+#define TIMEOUT (10*TICKS_PER_SEC)
+
+/* These settings have sense only if compiled with -DCONGESTED */
+/* total retransmission timeout in ticks */
+#define TFTP_TIMEOUT (30*TICKS_PER_SEC)
+/* packet retransmission timeout in ticks */
+#define TFTP_REXMT (3*TICKS_PER_SEC)
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define TRUE 1
+#define FALSE 0
+
+#define ETHER_ADDR_SIZE 6 /* Size of Ethernet address */
+#define ETHER_HDR_SIZE 14 /* Size of ethernet header */
+#define ETH_MIN_PACKET 64
+#define ETH_MAX_PACKET 1518
+
+#define VENDOR_NONE 0
+#define VENDOR_WD 1
+#define VENDOR_NOVELL 2
+#define VENDOR_3COM 3
+#define VENDOR_3C509 4
+#define VENDOR_CS89x0 5
+
+#define FLAG_PIO 0x01
+#define FLAG_16BIT 0x02
+#define FLAG_790 0x04
+
+#define ARP_CLIENT 0
+#define ARP_SERVER 1
+#define ARP_GATEWAY 2
+#define ARP_ROOTSERVER 3
+#define ARP_SWAPSERVER 4
+#define MAX_ARP ARP_SWAPSERVER+1
+
+#define RARP_REQUEST 3
+#define RARP_REPLY 4
+
+#define IP 0x0800
+#define ARP 0x0806
+#define RARP 0x8035
+
+#define BOOTP_SERVER 67
+#define BOOTP_CLIENT 68
+#define TFTP_PORT 69
+#define SUNRPC_PORT 111
+
+#define IP_UDP 17
+/* Same after going through htonl */
+#define IP_BROADCAST 0xFFFFFFFF
+
+#define ARP_REQUEST 1
+#define ARP_REPLY 2
+
+#define BOOTP_REQUEST 1
+#define BOOTP_REPLY 2
+
+#define TAG_LEN(p) (*((p)+1))
+#define RFC1533_COOKIE 99, 130, 83, 99
+#define RFC1533_PAD 0
+#define RFC1533_NETMASK 1
+#define RFC1533_TIMEOFFSET 2
+#define RFC1533_GATEWAY 3
+#define RFC1533_TIMESERVER 4
+#define RFC1533_IEN116NS 5
+#define RFC1533_DNS 6
+#define RFC1533_LOGSERVER 7
+#define RFC1533_COOKIESERVER 8
+#define RFC1533_LPRSERVER 9
+#define RFC1533_IMPRESSSERVER 10
+#define RFC1533_RESOURCESERVER 11
+#define RFC1533_HOSTNAME 12
+#define RFC1533_BOOTFILESIZE 13
+#define RFC1533_MERITDUMPFILE 14
+#define RFC1533_DOMAINNAME 15
+#define RFC1533_SWAPSERVER 16
+#define RFC1533_ROOTPATH 17
+#define RFC1533_EXTENSIONPATH 18
+#define RFC1533_IPFORWARDING 19
+#define RFC1533_IPSOURCEROUTING 20
+#define RFC1533_IPPOLICYFILTER 21
+#define RFC1533_IPMAXREASSEMBLY 22
+#define RFC1533_IPTTL 23
+#define RFC1533_IPMTU 24
+#define RFC1533_IPMTUPLATEAU 25
+#define RFC1533_INTMTU 26
+#define RFC1533_INTLOCALSUBNETS 27
+#define RFC1533_INTBROADCAST 28
+#define RFC1533_INTICMPDISCOVER 29
+#define RFC1533_INTICMPRESPOND 30
+#define RFC1533_INTROUTEDISCOVER 31
+#define RFC1533_INTROUTESOLICIT 32
+#define RFC1533_INTSTATICROUTES 33
+#define RFC1533_LLTRAILERENCAP 34
+#define RFC1533_LLARPCACHETMO 35
+#define RFC1533_LLETHERNETENCAP 36
+#define RFC1533_TCPTTL 37
+#define RFC1533_TCPKEEPALIVETMO 38
+#define RFC1533_TCPKEEPALIVEGB 39
+#define RFC1533_NISDOMAIN 40
+#define RFC1533_NISSERVER 41
+#define RFC1533_NTPSERVER 42
+#define RFC1533_VENDOR 43
+#define RFC1533_NBNS 44
+#define RFC1533_NBDD 45
+#define RFC1533_NBNT 46
+#define RFC1533_NBSCOPE 47
+#define RFC1533_XFS 48
+#define RFC1533_XDM 49
+#ifndef NO_DHCP_SUPPORT
+#define RFC2132_REQ_ADDR 50
+#define RFC2132_MSG_TYPE 53
+#define RFC2132_SRV_ID 54
+#define RFC2132_PARAM_LIST 55
+#define RFC2132_MAX_SIZE 57
+
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPACK 5
+#endif /* NO_DHCP_SUPPORT */
+
+#define RFC1533_VENDOR_MAJOR 0
+#define RFC1533_VENDOR_MINOR 0
+
+#define RFC1533_VENDOR_MAGIC 128
+#define RFC1533_VENDOR_ADDPARM 129
+#ifdef IMAGE_FREEBSD
+#define RFC1533_VENDOR_HOWTO 132
+#endif
+#define RFC1533_VENDOR_MNUOPTS 160
+#define RFC1533_VENDOR_SELECTION 176
+#define RFC1533_VENDOR_MOTD 184
+#define RFC1533_VENDOR_NUMOFMOTD 8
+#define RFC1533_VENDOR_IMG 192
+#define RFC1533_VENDOR_NUMOFIMG 16
+
+#define RFC1533_END 255
+#define BOOTP_VENDOR_LEN 64
+#ifndef NO_DHCP_SUPPORT
+#define DHCP_OPT_LEN 312
+#endif /* NO_DHCP_SUPPORT */
+
+#define TFTP_DEFAULTSIZE_PACKET 512
+#define TFTP_MAX_PACKET 1432 /* 512 */
+
+#define TFTP_RRQ 1
+#define TFTP_WRQ 2
+#define TFTP_DATA 3
+#define TFTP_ACK 4
+#define TFTP_ERROR 5
+#define TFTP_OACK 6
+
+#define TFTP_CODE_EOF 1
+#define TFTP_CODE_MORE 2
+#define TFTP_CODE_ERROR 3
+#define TFTP_CODE_BOOT 4
+#define TFTP_CODE_CFG 5
+
+#define AWAIT_ARP 0
+#define AWAIT_BOOTP 1
+#define AWAIT_TFTP 2
+#define AWAIT_RARP 3
+#define AWAIT_RPC 4
+#define AWAIT_QDRAIN 5 /* drain queue, process ARP requests */
+
+typedef struct {
+ unsigned long s_addr;
+} in_addr;
+
+struct arptable_t {
+ in_addr ipaddr;
+ unsigned char node[6];
+};
+
+/*
+ * A pity sipaddr and tipaddr are not longword aligned or we could use
+ * in_addr. No, I don't want to use #pragma packed.
+ */
+struct arprequest {
+ unsigned short hwtype;
+ unsigned short protocol;
+ char hwlen;
+ char protolen;
+ unsigned short opcode;
+ char shwaddr[6];
+ char sipaddr[4];
+ char thwaddr[6];
+ char tipaddr[4];
+};
+
+struct iphdr {
+ char verhdrlen;
+ char service;
+ unsigned short len;
+ unsigned short ident;
+ unsigned short frags;
+ char ttl;
+ char protocol;
+ unsigned short chksum;
+ in_addr src;
+ in_addr dest;
+};
+
+struct udphdr {
+ unsigned short src;
+ unsigned short dest;
+ unsigned short len;
+ unsigned short chksum;
+};
+
+struct bootp_t {
+ struct iphdr ip;
+ struct udphdr udp;
+ char bp_op;
+ char bp_htype;
+ char bp_hlen;
+ char bp_hops;
+ unsigned long bp_xid;
+ unsigned short bp_secs;
+ unsigned short unused;
+ in_addr bp_ciaddr;
+ in_addr bp_yiaddr;
+ in_addr bp_siaddr;
+ in_addr bp_giaddr;
+ char bp_hwaddr[16];
+ char bp_sname[64];
+ char bp_file[128];
+#ifdef NO_DHCP_SUPPORT
+ char bp_vend[BOOTP_VENDOR_LEN];
+#else
+ char bp_vend[DHCP_OPT_LEN];
+#endif /* NO_DHCP_SUPPORT */
+};
+
+struct bootpd_t {
+ struct bootp_t bootp_reply;
+ unsigned char bootp_extension[MAX_BOOTP_EXTLEN];
+};
+
+struct tftp_t {
+ struct iphdr ip;
+ struct udphdr udp;
+ unsigned short opcode;
+ union {
+ char rrq[TFTP_DEFAULTSIZE_PACKET];
+ struct {
+ unsigned short block;
+ char download[TFTP_MAX_PACKET];
+ } data;
+ struct {
+ unsigned short block;
+ } ack;
+ struct {
+ unsigned short errcode;
+ char errmsg[TFTP_DEFAULTSIZE_PACKET];
+ } err;
+ struct {
+ char data[TFTP_DEFAULTSIZE_PACKET + 2];
+ } oack;
+ } u;
+};
+
+#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
+
+struct rpc_t {
+ struct iphdr ip;
+ struct udphdr udp;
+ union {
+ char data[300]; /* longest RPC call must fit!!!! */
+ struct {
+ long id;
+ long type;
+ long rpcvers;
+ long prog;
+ long vers;
+ long proc;
+ long data[1];
+ } call;
+ struct {
+ long id;
+ long type;
+ long rstatus;
+ long verifier;
+ long v2;
+ long astatus;
+ long data[1];
+ } reply;
+ } u;
+};
+
+#define PROG_PORTMAP 100000
+#define PROG_NFS 100003
+#define PROG_MOUNT 100005
+
+#define MSG_CALL 0
+#define MSG_REPLY 1
+
+#define PORTMAP_GETPORT 3
+
+#define MOUNT_ADDENTRY 1
+#define MOUNT_UMOUNTALL 4
+
+#define NFS_LOOKUP 4
+#define NFS_READ 6
+
+#define NFS_FHSIZE 32
+
+#define NFSERR_PERM 1
+#define NFSERR_NOENT 2
+#define NFSERR_ACCES 13
+
+/* Block size used for NFS read accesses. A RPC reply packet (including all
+ * headers) must fit within a single Ethernet frame to avoid fragmentation.
+ * Chosen to be a power of two, as most NFS servers are optimized for this. */
+#define NFS_READ_SIZE 1024
+
+#define FLOPPY_BOOT_LOCATION 0x7c00
+
+#define ROM_INFO_LOCATION 0x7dfa
+/* at end of floppy boot block */
+
+struct rom_info {
+ unsigned short rom_segment;
+ unsigned short rom_length;
+};
+
+/***************************************************************************
+External prototypes
+***************************************************************************/
+/* main.c */
+extern void print_bytes P((unsigned char *bytes, int len));
+extern void load P((void));
+extern int load_linux P((int root_mount_port, int swap_mount_port,
+ int root_nfs_port, char *kernel_handle));
+extern int downloadkernel P((unsigned char *, int, int, int));
+extern int tftp
+P((const char *name, int (*)(unsigned char *, int, int, int)));
+extern void rpc_init(void);
+extern int nfs
+P((const char *name, int (*)(unsigned char *, int, int, int)));
+extern void nfs_umountall P((int));
+extern int bootp P((void));
+extern int rarp P((void));
+extern int udp_transmit P((unsigned long destip, unsigned int srcsock,
+ unsigned int destsock, int len,
+ const void *buf));
+
+extern int await_reply P((int type, int ival, void *ptr, int timeout));
+extern int decode_rfc1533 P((unsigned char *, int, int, int));
+extern unsigned short ipchksum P((unsigned short *, int len));
+extern void rfc951_sleep P((int));
+extern void cleanup_net P((void));
+extern void cleanup P((void));
+
+/* config.c */
+extern void print_config(void);
+extern void eth_reset(void);
+extern int eth_probe(void);
+extern int eth_poll(void);
+extern void eth_transmit(const char *d, unsigned int t, unsigned int s,
+ const void *p);
+extern void eth_disable(void);
+
+/* bootmenu.c */
+extern int execute P((char *string));
+extern void bootmenu P((int));
+extern void show_motd P((void));
+extern void parse_menuopts P((char *, int));
+extern int getoptvalue P((char **, int *, int *));
+extern void selectImage P((char **));
+
+/* osloader.c */
+#if defined(AOUT_IMAGE) || defined(ELF_IMAGE)
+extern int howto;
+#endif
+extern int os_download P((unsigned int, unsigned char *, unsigned int));
+
+/* misc.c */
+extern void twiddle P((void));
+extern void sleep P((int secs));
+extern int strcasecmp P((char *a, char *b));
+extern char *substr P((char *a, char *b));
+extern int getdec P((char **));
+extern void printf P((const char *, ...));
+extern char *sprintf P((char *, const char *, ...));
+extern int inet_aton P((char *p, in_addr * i));
+extern void gateA20_set P((void));
+extern void gateA20_unset P((void));
+extern void putchar P((int));
+extern int getchar P((void));
+extern int iskey P((void));
+
+/* start*.S */
+extern int getc P((void));
+extern void putc P((int));
+extern int ischar P((void));
+extern int getshift P((void));
+extern unsigned int memsize P((void));
+extern unsigned short basememsize P((void));
+extern void disk_init P((void));
+extern unsigned int disk_read P((int drv, int c, int h, int s, char *buf));
+extern void xstart P((unsigned long, unsigned long, char *));
+extern unsigned long currticks P((void));
+extern int setjmp P((void *jmpbuf));
+extern void longjmp P((void *jmpbuf, int where));
+extern void exit P((int status));
+extern void slowdownio P((void));
+
+/* serial.S */
+extern int serial_getc P((void));
+extern void serial_putc P((int));
+extern int serial_ischar P((void));
+extern int serial_init P((void));
+
+/* ansiesc.c */
+extern void ansi_reset P((void));
+extern void enable_cursor P((int));
+extern void handleansi P((unsigned char));
+
+/* md5.c */
+extern void md5_put P((unsigned int ch));
+extern void md5_done P((unsigned char *buf));
+
+/* floppy.c */
+extern int bootdisk P((int dev, int part));
+
+/***************************************************************************
+External variables
+***************************************************************************/
+/* main.c */
+extern const char *kernel;
+extern char kernel_buf[128];
+extern struct rom_info rom;
+extern int hostnamelen;
+extern unsigned long netmask;
+extern int jmp_bootmenu[10];
+extern struct arptable_t arptable[MAX_ARP];
+#ifdef IMAGE_MENU
+extern char *motd[RFC1533_VENDOR_NUMOFMOTD];
+extern int menutmo, menudefault;
+extern unsigned char *defparams;
+extern int defparams_max;
+#endif
+#if defined(ETHERBOOT32) && !defined(INTERNAL_BOOTP_DATA)
+#define BOOTP_DATA_ADDR ((struct bootpd_t *)0x93C00)
+#else
+extern struct bootpd_t bootp_data;
+#define BOOTP_DATA_ADDR (&bootp_data)
+#endif
+extern unsigned char *end_of_rfc1533;
+#ifdef IMAGE_FREEBSD
+extern int freebsd_howto;
+#endif
+
+/* config.c */
+extern struct nic nic;
+
+/* bootmenu.c */
+
+/* osloader.c */
+
+/* created by linker */
+extern char _start[], _edata[], _end[];
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c b/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c
new file mode 100644
index 000000000..41b89f1e8
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/evb64120A_Setup.c
@@ -0,0 +1,199 @@
+/*
+ * arch/mips/galileo/compressed/evb64120A_memSetup.c
+ *
+ * By RidgeRun Inc, (Leveraged from Galileo's sbd.c)
+ *
+ * Xfer an image from flash to ram.
+ * For use with Galileo EVB64120A MIPS eval board.
+ */
+
+#include <linux/config.h>
+#include "ns16550.h"
+#include <linux/serial_reg.h>
+#include <asm/galileo-boards/evb64120A/pci.h>
+#include <asm/galileo-boards/evb64120A/core.h>
+
+void XferToRam(void);
+bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length,
+ unsigned int bank1Base, unsigned int bank1Length);
+bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length,
+ unsigned int bank3Base, unsigned int bank3Length);
+bool mapDevices0_1and2MemorySpace(unsigned int device0Base,
+ unsigned int device0Length,
+ unsigned int device1Base,
+ unsigned int device1Length,
+ unsigned int device2Base,
+ unsigned int device2Length);
+
+#define RUNNINGFROMFLASH
+#include "./xfer.c"
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+unsigned int readWord(unsigned int addr)
+{
+ unsigned int tmp;
+ tmp = *(unsigned int *) (addr | NONE_CACHEABLE);
+ return WORDSWAP(tmp);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void writeWord(unsigned int addr, unsigned int data)
+{
+ *((unsigned int *) (addr | NONE_CACHEABLE)) = WORDSWAP(data);
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+unsigned int GetExtendedMemorySize(void)
+{
+ unsigned int address, data = 0x11223344, type;
+ unsigned int bank1_ef = false, bank2_ef = false, bank3_ef = false;
+ unsigned int bank0_size, bank2_size, bank3_size, total_size = 0;
+
+ mapMemoryBanks0and1(0, 0x800000, 0x800000, 0x800000);
+ mapMemoryBanks2and3(0x1000000, 0x800000, 0x1800000, 0x800000);
+ type = readWord(0x14000810);
+ switch (type) {
+ case 16:
+ bank0_size = 0x1000000;
+ break;
+ case 64:
+ bank0_size = 0x4000000;
+ break;
+ case 128:
+ bank0_size = 0x8000000;
+ break;
+ case 256:
+ bank0_size = 0x10000000;
+ break;
+ default:
+ bank0_size = 0x1000000;
+ break;
+ }
+
+ type = readWord(0x14000814);
+ switch (type) {
+ case 16:
+ bank2_size = 0x1000000;
+ bank3_size = 0x1000000;
+ break;
+ case 64:
+ bank2_size = 0x4000000;
+ bank3_size = 0x4000000;
+ break;
+ case 128:
+ bank2_size = 0x8000000;
+ bank3_size = 0x8000000;
+ break;
+ case 256:
+ bank2_size = 0x10000000;
+ bank3_size = 0x10000000;
+ break;
+ default:
+ bank2_size = 0x1000000;
+ bank3_size = 0x1000000;
+ break;
+ }
+
+ /* Check which banks exist */
+ /* Bank 1 */
+ for (address = 0xffff00; address < 0x1000000; address += 4)
+ writeWord(address, data);
+ for (address = 0xffff00; address < 0x1000000; address += 4) {
+ if (readWord(address) != data)
+ break;
+ }
+ if (address == 0x1000000)
+ bank1_ef = true;
+ // Bank 2
+ for (address = 0x17fff00; address < 0x1800000; address += 4)
+ writeWord(address, data);
+ for (address = 0x17fff00; address < 0x1800000; address += 4) {
+ if (readWord(address) != data)
+ break;
+ }
+ if (address == 0x1800000)
+ bank2_ef = true;
+ else
+ bank2_size = 0x0;
+ // Bank 3
+ for (address = 0x1ffff00; address < 0x2000000; address += 4)
+ writeWord(address, data);
+ for (address = 0x1ffff00; address < 0x2000000; address += 4) {
+ if (readWord(address) != data)
+ break;
+ }
+ if (address == 0x2000000)
+ bank3_ef = true;
+
+ // Reconfig the system with the new bank0 (and maybe bank1) size.
+ if (bank0_size == 0x10000000)
+ bank1_ef = false;
+ if (bank1_ef == true) {
+ mapMemoryBanks0and1(0, bank0_size, bank0_size, bank0_size);
+ // Fix the PCI bars
+ pci0MapMemoryBanks0_1(0, bank0_size * 2);
+ pci1MapMemoryBanks0_1(0, bank0_size * 2);
+ total_size += bank0_size * 2;
+ } else {
+ mapMemoryBanks0and1(0, bank0_size, bank0_size, 0);
+ // Fix the PCI bars
+ pci0MapMemoryBanks0_1(0, bank0_size);
+ pci1MapMemoryBanks0_1(0, bank0_size);
+ total_size += bank0_size;
+ }
+ if (total_size == 0x10000000) {
+ bank2_ef = false;
+ bank3_ef = false;
+ } else {
+ if ((total_size + bank2_size) > 0x10000000) {
+ bank2_size = 0x10000000 - total_size;
+ bank3_ef = false;
+ } else {
+ if (bank3_size + total_size + bank2_size >
+ 0x10000000) {
+ bank3_size =
+ 0x10000000 - (total_size + bank2_size);
+ }
+ }
+ }
+ if (bank2_ef == true) {
+ if (bank3_ef == true) {
+ mapMemoryBanks2and3(total_size, bank2_size,
+ total_size + bank2_size,
+ bank3_size);
+ // Fix the PCI bars
+ pci0MapMemoryBanks2_3(total_size,
+ bank2_size + bank3_size);
+ pci1MapMemoryBanks2_3(total_size,
+ bank2_size + bank3_size);
+ total_size += (bank2_size + bank3_size);
+ } else {
+ mapMemoryBanks2and3(total_size, bank2_size,
+ total_size + bank2_size, 0);
+ // Fix the PCI bars
+ pci0MapMemoryBanks2_3(total_size, bank2_size);
+ pci1MapMemoryBanks2_3(total_size, bank2_size);
+ total_size += bank2_size;
+ }
+ } else {
+ mapMemoryBanks2and3(total_size, 0, total_size, 0);
+ pci0MapMemoryBanks2_3(total_size, 0);
+ pci1MapMemoryBanks2_3(total_size, 0);
+ }
+ /* Reorganize the devices memory map */
+ mapDevices0_1and2MemorySpace(0x1c000000, 0x800000, 0x1a000000,
+ 0xc00000, 0x1d000000, 0x800000);
+
+ XferToRam();
+ return 0; // Not that we'll ever get to this line of code, but
+ // it does satisfy a compiler warning.
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/fixit b/arch/mips/galileo-boards/ev64120/compressed/fixit
new file mode 100644
index 000000000..5f4dcdc59
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/fixit
@@ -0,0 +1,17 @@
+#!/bin/ksh
+
+# By RidgeRun Inc.
+#
+# The input to this script is
+# intended to be a *.S file which
+# was previously created by the doit
+# program. That program constructs
+# a *.S file which has a defined data
+# table containing values with leading
+# zeroes. To satisfy our assembler those
+# leading zeroes need to be stripped off
+# and that is the purpose of this script.
+
+echo "Removing leading zeros"
+sed -e "s/ 0\(.\)/ \1/g" $1 | sed -e "s/ 0\(.\)/ \1/g" > $1.new
+mv $1.new $1
diff --git a/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c b/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c
new file mode 100644
index 000000000..8296fe83b
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/flashdrv.c
@@ -0,0 +1,1560 @@
+/* flashdrv.c - FLASH memory functions and definitions*/
+
+/* Copyright Galileo Technology. */
+
+/*
+DESCRIPTION
+This flash driver gives the user a convenient interface to FLASH memory located
+on the user`s board, it supports various layout configurations such as:
+1. One pure 8 bit device (Such as AMD`s AM29LV040B).
+2. 1,2,4 or 8 devices 16 bit wide configured to operate in 8 bit mode.
+3. 1,2 or 4 devices each 16 bit wide.
+Before using the driver you must call the initialization function at least once
+or when ever you are changing the FLASH base address.
+The list bellow contains the supported FLASH memory devices, new devices can be
+added easily in the future.
+*/
+
+/*includes*/
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/flashdrv.h>
+#else
+#include "flashdrv.h"
+#endif
+/* locals */
+
+#ifdef __MIPSEB__ // skranz, add
+#define BE // skranz, add
+#endif // skranz, add
+
+/******************************************************************************
+* Those two tables contain the supported flash devices information needed by
+* the driver:
+* The first table "flashParametrs" starts with 10 shared fields
+* (currently 6 are reserved):
+* index 0 => Pointer to an entry in the second table list
+* index 1 => baseAddress - Flash memory device base address.
+* index 2 => width - 1, 2, 4 or 8 Bytes.
+* index 3 => mode - PURE8, X8 or X16 flash configuration (for X16 devices only)
+* The second table (flashTypes) contains:
+* Entry`s structure:
+* Manufacture ID,Device ID,number of sectors,list of sector`s sizes
+* (in Kbytes starting with sector number 0).
+* The end of the list is pointed with a zero.
+******************************************************************************/
+unsigned int flashParametrs[10]; /* 0 Entry pointer */
+ /* 0 Base address */
+ /* 0 Width */
+ /* 0 Mode */
+ /* 0,0,0,0,0,0, spare entries. */
+unsigned int flashTypes[] = {
+
+ /* 0 */ AMD_FLASH, AM29F400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64,
+ 64, 64, 64,
+ /* 1 */ AMD_FLASH, AM29F400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32,
+ 8, 8, 16,
+ /* 2 */ ST_FLASH, M29W040, 8, 64, 64, 64, 64, 64, 64, 64, 64,
+ /* 3 */ AMD_FLASH, AM29LV040B, 8, 64, 64, 64, 64, 64, 64, 64, 64,
+ /* 4 */ AMD_FLASH, AM29LV800BT, 19, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 32, 8, 8, 16,
+ /* 5 */ INTEL_FLASH, I28F320J3A, 32, 128, 128, 128, 128, 128, 128,
+ 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128,
+ /* 6 */ INTEL_FLASH, I28F640J3A, 64, 128, 128, 128, 128, 128, 128,
+ 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128,
+ /* 7 */ INTEL_FLASH, I28F128J3A, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ /* 8 */ AMD_FLASH, AM29LV400BB, 11, 16, 8, 8, 32, 64, 64, 64, 64,
+ 64, 64, 64,
+ /* 9 */ AMD_FLASH, AM29LV400BT, 11, 64, 64, 64, 64, 64, 64, 64, 32,
+ 8, 8, 16,
+ /* 10 */ INTEL_FLASH, I28F320B3_T, 71, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 8, 8, 8, 8, 8, 8, 8, 8,
+ /* 11 */ INTEL_FLASH, I28F320B3_B, 71, 8, 8, 8, 8, 8, 8, 8, 8, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ /* 12 */ INTEL_FLASH, I28F160B3_B, 39, 8, 8, 8, 8, 8, 8, 8, 8, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64,
+ /* 13 */ INTEL_FLASH, I28F160B3_T, 39, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64, 8, 8, 8, 8, 8, 8, 8, 8,
+
+ 0 /* End of list indicator */
+};
+
+/********************************************************************
+* flashInit - Initializes the FLASH memory driver`s parameters, this function
+* must be called at least once before using the FLASH memory.
+* If you are changing the FLASH base address call this function
+* again.
+*
+* INPUTS: unsigned int flashBaseAddress - The flash base Address.
+* unsigned int flashWidth - Flash bus width in Bytes: 1,2,4 or 8.
+* flashMode - PURE8, X8 or X16.
+* RETURNS: Flash Size, zero when operation (flashInit) failed.
+*********************************************************************/
+unsigned int flashInit(unsigned int flashBaseAddress,
+ unsigned int flashWidth, FLASHmode flashMode)
+{
+ unsigned short mfrId = 0;
+ unsigned short devId = 0xffff;
+ unsigned int FirstAddr, SecondAddr, ThirdAddr;
+ unsigned int pArray = 0;
+ unsigned int counter;
+ unsigned int flashSize = 0;
+
+ /* update the list with relevant parametrs */
+ flashParametrs[0] = 0; /* Default initialization */
+ flashParametrs[1] = flashBaseAddress;
+ flashParametrs[2] = flashWidth;
+ flashParametrs[3] = flashMode;
+ /* Get the FLASH`s ID */
+ switch (FLASH_WIDTH) {
+ case 1:
+ /* AMD or ST ?? * */
+ if (flashMode == PURE8) { /* Boot Flash */
+ FirstAddr = 0x5555;
+ SecondAddr = 0x2aaa;
+ ThirdAddr = 0x5555;
+ } else { /* X16 device configured to 8bit Mode */
+
+ FirstAddr = 0xaaaa;
+ SecondAddr = 0x5555;
+ ThirdAddr = 0xaaaa;
+ }
+ flashReset();
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90);
+ READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId);
+ if (mfrId == AMD_FLASH || mfrId == ST_FLASH) {
+ flashReset();
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x90);
+ READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId);
+ break;
+ }
+ /* Micron or Intel ?? * */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff); /* Read Array */
+ /* Flash reset for Intel/Micron */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90); /* IDENTIFY Device */
+ READ_CHAR(FLASH_BASE_ADDRESS + 0x0, &mfrId); /*Address for ManufactureID */
+ if (mfrId == INTEL_FLASH || mfrId == MICRON_FLASH) {
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0xff); /* Read Array */
+ /*Flash reset for Intel/Micron */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x90); /* IDENTIFY Device */
+ READ_CHAR(FLASH_BASE_ADDRESS + 0x1, &devId); /*Address for DeviceID */
+ }
+ break;
+ case 2:
+ case 4:
+ case 8:
+ /* AMD or ST ??? */
+ flashReset();
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH,
+ 0xaa);
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 0x2aaa * FLASH_WIDTH,
+ 0x55);
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 0x5555 * FLASH_WIDTH,
+ 0x90);
+ READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+ flashReset();
+ /* Read the device ID */
+ if (mfrId == AMD_FLASH || mfrId == ST_FLASH) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ 0x5555 * FLASH_WIDTH, 0xaa);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ 0x2aaa * FLASH_WIDTH, 0x55);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ 0x5555 * FLASH_WIDTH, 0x90);
+ READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH,
+ &devId);
+ break;
+ }
+ /* Micron or Intel ?? * */
+ WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff);
+ WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090);
+ if ((FLASH_WIDTH == 4) || (FLASH_WIDTH == 8)) { /* 32 or 64 bit */
+ READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+ } else { /* FLASH_WIDTH = 2 */
+
+ READ_SHORT(FLASH_BASE_ADDRESS, &mfrId);
+ }
+ if ((mfrId == INTEL_FLASH) || (mfrId == MICRON_FLASH)) {
+ /* Flash reset for Intel/Micron */
+ flashReset();
+ WRITE_WORD(FLASH_BASE_ADDRESS, 0x00ff00ff);
+ WRITE_WORD(FLASH_BASE_ADDRESS, 0x00900090);
+ READ_SHORT(FLASH_BASE_ADDRESS + 0x1 * FLASH_WIDTH,
+ &devId);
+ }
+ break;
+
+ }
+ /* Try to locate the device in the supported flashes list (FLASH_TYPE).
+ according to the keys:
+ 1) mfrId - manufactor ID.
+ 2) devId - device ID.
+ */
+
+ while (true) {
+ if (flashTypes[pArray] == 0) {
+ flashReset();
+ return 0; /* Device not in the list */
+ }
+ if ((flashTypes[pArray] == mfrId) &&
+ (flashTypes[pArray + 1] == devId)) {
+ POINTER_TO_FLASH = pArray;
+ for (counter = 0;
+ counter < flashTypes[NUMBER_OF_SECTORS];
+ counter++) {
+ flashSize =
+ flashSize +
+ flashTypes[FIRST_SECTOR_SIZE +
+ counter];
+ }
+ if (FLASH_MODE != PURE8) {
+ flashReset();
+ return (flashSize * _1K *
+ (FLASH_WIDTH / (FLASH_MODE / 8)));
+ } else {
+ flashReset();
+ return (flashSize * _1K * FLASH_WIDTH);
+ }
+ }
+ pArray += (3 + flashTypes[pArray + 2]); /* Move to next entry */
+ }
+}
+
+/********************************************************************
+* flashReset - Resets the Flash memory (FLASH`s internal protocol reset).
+*
+* INTPUTS: N/A
+* OUTPUT: N/A
+*********************************************************************/
+void flashReset()
+{
+ unsigned char ucData;
+ unsigned short usData;
+ unsigned int uiData;
+
+ if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) ||
+ (flashTypes[POINTER_TO_FLASH]) == ST_FLASH) {
+ if (FLASH_MODE == X16) {
+ ucData = 0xf0;
+ usData = 0xf0;
+ uiData = 0x00f000f0;
+ } else { /* case of PURE8 or X8 */
+
+ ucData = 0xf0;
+ usData = 0xf0f0;
+ uiData = 0xf0f0f0f0;
+ }
+ } else {
+ if (FLASH_MODE == X16) {
+ ucData = 0xff;
+ usData = 0xff;
+ uiData = 0x00ff00ff;
+ } else { /* case of PURE8 or X8 */
+
+ ucData = 0xff;
+ usData = 0xffff;
+ uiData = 0xffffffff;
+ }
+ }
+ switch (FLASH_WIDTH) {
+ case 1:
+ WRITE_CHAR(FLASH_BASE_ADDRESS, ucData);
+ break;
+ case 2:
+ WRITE_SHORT(FLASH_BASE_ADDRESS, usData);
+ break;
+ case 4:
+ WRITE_WORD(FLASH_BASE_ADDRESS, uiData);
+ break;
+ case 8:
+ WRITE_WORD(FLASH_BASE_ADDRESS, uiData);
+ WRITE_WORD(FLASH_BASE_ADDRESS + 0x4, uiData);
+ break;
+ }
+}
+
+/********************************************************************
+* flashErase - The function erases the WHOLE flash memory.
+*
+*
+* RETURNS: true on success,false on failure
+*********************************************************************/
+bool flashErase()
+{
+ unsigned int totalFlashSize;
+ unsigned int address;
+ unsigned int readData;
+ unsigned int nextSector;
+
+ flashReset();
+ totalFlashSize = flashGetSize();
+ /* scan all flash memory space. */
+ address = 0;
+ while (address < totalFlashSize) {
+ readData = flashReadWord(address);
+ if (readData != 0xffffffff) { /* offset with dirty data. */
+ flashEraseSector(flashInWhichSector(address));
+ nextSector = flashInWhichSector(address) + 1;
+ if (nextSector < flashTypes[NUMBER_OF_SECTORS])
+ /* jump to next sector. */
+ address = flashGetSectorOffset(nextSector);
+ else
+ /* end of erasing. */
+ address = totalFlashSize;
+ } else
+ address += 4;
+ }
+ return true;
+}
+
+/********************************************************************
+* flashEraseSector - The function erases a specific sector in the flash memory.
+*
+* INPUTS: Sector number.
+* RETURNS: true on success,false on failure.
+*********************************************************************/
+bool flashEraseSector(unsigned int sectorNumber)
+{
+ volatile unsigned int spin;
+ unsigned int regValue;
+ unsigned int sectorBaseAddress = 0;
+ unsigned int i;
+ unsigned int data20, dataD0, data70;
+ unsigned int dataPoll;
+ unsigned int FirstAddr, SecondAddr, ThirdAddr, FourthAddr,
+ FifthAddr;
+ unsigned int FirstData, SecondData, ThirdData;
+ unsigned int FourthData, FifthData, SixthData;
+
+ /* calculate the sector base Address according to the following parametrs:
+ 1: FLASH_WIDTH
+ 2: the size of each sector which it detailed in the table */
+
+ /* checking the if the sectorNumber is legal. */
+ if (sectorNumber > flashTypes[NUMBER_OF_SECTORS] - 1)
+ return false;
+ /* now the calculation begining of the sector Address */
+ for (i = 0; i < sectorNumber; i++) {
+ sectorBaseAddress =
+ sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i];
+ }
+ /* In case of X8 wide the address should be */
+ if (FLASH_MODE == PURE8)
+ sectorBaseAddress = _1K * sectorBaseAddress;
+ if (FLASH_MODE == X8)
+ sectorBaseAddress = _1K * sectorBaseAddress;
+ /* In case of X16 wide the address should be */
+ if (FLASH_MODE == X16)
+ sectorBaseAddress = _1K * sectorBaseAddress / 2;
+ flashReset();
+ if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \
+ (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) {
+ switch (FLASH_WIDTH) {
+ case 1:
+ if (FLASH_MODE == PURE8) { /* Boot Flash PURE8 */
+ FirstAddr = 0x5555;
+ SecondAddr = 0x2aaa;
+ ThirdAddr = 0x5555;
+ FourthAddr = 0x5555;
+ FifthAddr = 0x2aaa;
+ } else {
+ FirstAddr = 0xaaaa;
+ SecondAddr = 0x5555;
+ ThirdAddr = 0xaaaa;
+ FourthAddr = 0xaaaa;
+ FifthAddr = 0x5555;
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xAA);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0x80);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FourthAddr, 0xAA);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FifthAddr, 0x55);
+ WRITE_CHAR(
+ (FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00)),
+ 0x30);
+ /* Poll on the flash */
+ do {
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ sectorBaseAddress, &regValue);
+ } while ((regValue & 0x80) != 0x80);
+
+ break;
+ case 2:
+ if (FLASH_MODE == X16) {
+ FirstData = 0xaa; /* Data for the First Cycle */
+ SecondData = 0x55; /* Data for the Second Cycle */
+ ThirdData = 0x80; /* Data for the Third Cycle */
+ FourthData = 0xaa; /* Data for the Fourth Cycle */
+ FifthData = 0x55; /* Data for the Fifth Cycle */
+ SixthData = 0x30; /* Data for the Sixth Cycle */
+ FirstAddr = 0x5555; /* Address for the First Cycle */
+ SecondAddr = 0x2aaa; /* Address for the Second Cycle */
+ ThirdAddr = 0x5555; /* Address for the Third Cycle */
+ FourthAddr = 0x5555; /* Address for the Fourth Cycle */
+ FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */
+ } else { /* (FLASH_MODE = 8) */
+
+ FirstData = 0xaaaa; /* Data for the First Cycle */
+ SecondData = 0x5555; /* Data for the Second Cycle */
+ ThirdData = 0x8080; /* Data for the Third Cycle */
+ FourthData = 0xaaaa; /* Data for the Fourth Cycle */
+ FifthData = 0x5555; /* Data for the Fifth Cycle */
+ SixthData = 0x3030; /* Data for the Sixth Cycle */
+ FirstAddr = 0xaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x5555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaa; /* Address for the Third Cycle */
+ FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */
+ FifthAddr = 0x5555; /* Address for the Fifth Cycle */
+ }
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FourthAddr * FLASH_WIDTH, FourthData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FifthAddr * FLASH_WIDTH, FifthData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00) *
+ FLASH_WIDTH, SixthData);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) { /* 1 device of 16 bit */
+ dataPoll = 0x0080;
+ } else { /* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */
+
+ dataPoll = 0x8080;
+ }
+ do {
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * FLASH_WIDTH,
+ &regValue);
+ for (spin = 0; spin < 100; spin++) {
+ } // skranz, added spin loop.
+ } while ((regValue & dataPoll) != dataPoll);
+ break;
+ case 4:
+ if (FLASH_MODE == X16) {
+ FirstData = 0x00aa00aa; /* Data for the First Cycle */
+ SecondData = 0x00550055; /* Data for the Second Cycle */
+ ThirdData = 0x00800080; /* Data for the Third Cycle */
+ FourthData = 0x00aa00aa; /* Data for the Fourth Cycle */
+ FifthData = 0x00550055; /* Data for the Fifth Cycle */
+ SixthData = 0x00300030; /* Data for the Sixth Cycle */
+ FirstAddr = 0x5555; /* Address for the First Cycle */
+ SecondAddr = 0x2aaa; /* Address for the Second Cycle */
+ ThirdAddr = 0x5555; /* Address for the Third Cycle */
+ FourthAddr = 0x5555; /* Address for the Fourth Cycle */
+ FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */
+ } else { /* if (FLASH_MODE == 8) */
+
+ FirstData = 0xaaaaaaaa; /* Data for the First Cycle */
+ SecondData = 0x55555555; /* Data for the Second Cycle */
+ ThirdData = 0x80808080; /* Data for the Third Cycle */
+ FourthData = 0xAAAAAAAA; /* Data for the Fourth Cycle */
+ FifthData = 0x55555555; /* Data for the Fifth Cycle */
+ SixthData = 0x30303030; /* Data for the Sixth Cycle */
+ FirstAddr = 0xaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x5555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaa; /* Address for the Third Cycle */
+ FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */
+ FifthAddr = 0x5555; /* Address for the Fifth Cycle */
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FourthAddr * FLASH_WIDTH, FourthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FifthAddr * FLASH_WIDTH, FifthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00) *
+ FLASH_WIDTH, SixthData);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */
+ dataPoll = 0x00800080;
+ } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+ dataPoll = 0x80808080;
+ }
+ do {
+ READ_WORD(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * FLASH_WIDTH,
+ &regValue);
+ } while ((regValue & dataPoll) != dataPoll);
+ break;
+ case 8: /* In case of 64bit width the transformation is 1->8 */
+ if (FLASH_MODE == X16) {
+ FirstData = 0x00aa00aa; /* Data for the First Cycle */
+ SecondData = 0x00550055; /* Data for the Second Cycle */
+ ThirdData = 0x00800080; /* Data for the Third Cycle */
+ FourthData = 0x00aa00aa; /* Data for the Fourth Cycle */
+ FifthData = 0x00550055; /* Data for the Fifth Cycle */
+ SixthData = 0x00300030; /* Data for the Sixth Cycle */
+ FirstAddr = 0x5555; /* Address for the First Cycle */
+ SecondAddr = 0x2aaa; /* Address for the Second Cycle */
+ ThirdAddr = 0x5555; /* Address for the Third Cycle */
+ FourthAddr = 0x5555; /* Address for the Fourth Cycle */
+ FifthAddr = 0x2aaa; /* Address for the Fifth Cycle */
+ } else { /* (FLASH_MODE = 8 */
+
+ FirstData = 0xaaaaaaaa; /* Data for the First Cycle */
+ SecondData = 0x55555555; /* Data for the Second Cycle */
+ ThirdData = 0x80808080; /* Data for the Third Cycle */
+ FourthData = 0xAAAAAAAA; /* Data for the Fourth Cycle */
+ FifthData = 0x55555555; /* Data for the Fifth Cycle */
+ SixthData = 0x30303030; /* Data for the Sixth Cycle */
+ FirstAddr = 0xaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x5555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaa; /* Address for the Third Cycle */
+ FourthAddr = 0xaaaa; /* Address for the Fourth Cycle */
+ FifthAddr = 0x5555; /* Address for the Fifth Cycle */
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FourthAddr * FLASH_WIDTH, FourthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FifthAddr * FLASH_WIDTH, FifthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00) *
+ FLASH_WIDTH, SixthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH + 4, FirstData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH + 4,
+ SecondData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH + 4, ThirdData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FourthAddr * FLASH_WIDTH + 4,
+ FourthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ FifthAddr * FLASH_WIDTH + 4, FifthData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00)
+ * FLASH_WIDTH + 4, SixthData);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */
+ dataPoll = 0x00800080;
+ } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+ dataPoll = 0x80808080;
+ }
+ do {
+ READ_WORD(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * FLASH_WIDTH,
+ &regValue);
+ } while ((regValue & dataPoll) != dataPoll);
+ do {
+ READ_WORD(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * FLASH_WIDTH +
+ 4, &regValue);
+ } while ((regValue & dataPoll) != dataPoll);
+ break;
+ default:
+ return false;
+ }
+ } /* End of 'flash erase sector' for AMD/ST */
+ else { /* Intel/Micron */
+
+ switch (FLASH_WIDTH) {
+ case 1:
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x20);
+ WRITE_CHAR(
+ (FLASH_BASE_ADDRESS +
+ (sectorBaseAddress & 0xffffff00)),
+ 0xd0);
+ /* Poll on the flash */
+ while (true) {
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+ READ_CHAR(FLASH_BASE_ADDRESS, &regValue);
+ if ((regValue & 0x80) == 0x80)
+ break;
+ }
+ break;
+ case 2:
+ if (FLASH_MODE == X16) { /* 1 device 16 bit. */
+ data20 = 0x0020;;
+ dataD0 = 0x00d0;;
+ } else { /* (FLASH_MODE = 8) ==> 2 devices , 8 bit each => 16bit */
+
+ data20 = 0x2020;
+ dataD0 = 0xd0d0;
+ }
+ WRITE_SHORT(FLASH_BASE_ADDRESS, data20);
+ WRITE_SHORT(
+ (FLASH_BASE_ADDRESS +
+ ((sectorBaseAddress * 2) &
+ 0xffffff00)), dataD0);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) {
+ dataPoll = 0x0080;
+ data70 = 0x0070;
+ } else { /* (FLASH_MODE = 8) */
+
+ dataPoll = 0x8080;
+ data70 = 0x7070;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * 2, data70);
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * 2,
+ &regValue);
+ if ((regValue & 0x0080) == 0x0080)
+ break;
+ }
+ break;
+ case 4:
+ if (FLASH_MODE == X16) { /* 2 devices , 16 bit each => 32bit */
+ data20 = 0x00200020;
+ dataD0 = 0x00d000d0;
+ } else { /* (FLASH_MODE = 8) ==> 4 devices , 8 bit each => 32bit */
+
+ data20 = 0x20202020;
+ dataD0 = 0xd0d0d0d0;
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS, data20);
+ WRITE_WORD(
+ (FLASH_BASE_ADDRESS +
+ ((sectorBaseAddress * 4) &
+ 0xffffff00)), dataD0);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) {
+ dataPoll = 0x0080;
+ data70 = 0x0070;
+ } else { /* (FLASH_MODE = 8) */
+
+ dataPoll = 0x8080;
+ data70 = 0x7070;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS, data70);
+ READ_SHORT(FLASH_BASE_ADDRESS, &regValue);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+ data70);
+ READ_SHORT(FLASH_BASE_ADDRESS + 2,
+ &regValue);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ break;
+ case 8:
+ if (FLASH_MODE == X16) { /* 4 devices , 16 bit each => 64bit */
+ data20 = 0x00200020;
+ dataD0 = 0x00d000d0;
+ } else { /* (FLASH_MODE = 8) ==> 8 devices , 8 bit each => 64bit */
+
+ data20 = 0x20202020;
+ dataD0 = 0xd0d0d0d0;
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS, data20);
+ WRITE_WORD(
+ (FLASH_BASE_ADDRESS +
+ ((sectorBaseAddress * 8) &
+ 0xffffff00)), dataD0);
+ WRITE_WORD(FLASH_BASE_ADDRESS + 4, data20);
+ WRITE_WORD(
+ (FLASH_BASE_ADDRESS +
+ ((sectorBaseAddress * 8) & 0xffffff00 +
+ 4)), dataD0);
+ /* Poll on the flash */
+ if (FLASH_MODE == X16) {
+ dataPoll = 0x0080;
+ data70 = 0x0070;
+ } else { /* (FLASH_MODE = 8) */
+
+ dataPoll = 0x8080;
+ data70 = 0x7070;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * 8, data70);
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ sectorBaseAddress * 8,
+ &regValue);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+ data70);
+ READ_SHORT(FLASH_BASE_ADDRESS + 2,
+ &regValue);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 4,
+ data70);
+ READ_SHORT(FLASH_BASE_ADDRESS + 4,
+ &regValue);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 6,
+ data70);
+ READ_SHORT(FLASH_BASE_ADDRESS + 6,
+ &regValue);
+ if ((regValue & dataPoll) == dataPoll)
+ break;
+ }
+ break;
+ default:
+ return false;
+ }
+ }
+ flashReset();
+ return true;
+}
+
+/********************************************************************
+* flashWriteWord - Write 32Bit to the FLASH memory at the given offset from the
+* FLASH base address.
+* address 0 = 0x00000000 !!
+* Attention!!! data "0" cannot be programed back to
+* "1" (only by first performing an earase operation).
+* The function takes care of Big/Little endian conversion
+*
+* INPUTS: offset - The offset from the flash`s base address.
+* data - The data that should be written.
+* RETURNS: true on success,false on failure
+*********************************************************************/
+bool flashWriteWord(unsigned int offset, unsigned int data)
+{
+ unsigned char c, rc;
+ unsigned short s, rs;
+ register unsigned int rw;
+ register unsigned int regValue;
+ register unsigned int FirstAddr, SecondAddr, ThirdAddr;
+ register unsigned int FirstData, SecondData, ThirdData;
+ register unsigned int data10, data20, data70, data80;
+
+ if ((flashTypes[POINTER_TO_FLASH] == AMD_FLASH) || \
+ (flashTypes[POINTER_TO_FLASH] == ST_FLASH)) {
+ switch (FLASH_WIDTH) {
+ case 1: /* Split the 32 bit write into four 8bit Writings */
+ if (FLASH_MODE == PURE8) { /* Boot Flash */
+ FirstAddr = 0x5555;
+ SecondAddr = 0x2aaa;
+ ThirdAddr = 0x5555;
+ } else {
+ FirstAddr = 0xaaaa;
+ SecondAddr = 0x5555;
+ ThirdAddr = 0xaaaa;
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+ c = (data >> 24);
+#else
+ c = data;
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c);
+ /* Writing first Byte */
+ while (true) {
+ READ_CHAR(FLASH_BASE_ADDRESS + offset,
+ &rc);
+ if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ offset, &rc);
+ if ((rc & 0x80) == (c & 0x80))
+ break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+ c = (data >> 16);
+#else
+ c = (data >> 8);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c);
+ /* Writing second Byte */
+ while (true) {
+ READ_CHAR(FLASH_BASE_ADDRESS + offset + 1,
+ &rc);
+ if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ offset + 1, &rc);
+ if ((rc & 0x80) == (c & 0x80))
+ break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+ c = (data >> 8);
+#else
+ c = (data >> 16);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c);
+ /* Writing third Byte */
+ while (true) {
+ READ_CHAR(FLASH_BASE_ADDRESS + offset + 2,
+ &rc);
+ if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ offset + 2, &rc);
+ if ((rc & 0x80) == (c & 0x80))
+ break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ WRITE_CHAR(FLASH_BASE_ADDRESS + FirstAddr, 0xaa);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + SecondAddr, 0x55);
+ WRITE_CHAR(FLASH_BASE_ADDRESS + ThirdAddr, 0xa0);
+#ifdef BE
+ c = data;
+#else
+ c = (data >> 24);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c);
+ /* Writing fourth Byte */
+ while (true) {
+ READ_CHAR(FLASH_BASE_ADDRESS + offset + 3,
+ &rc);
+ if ((rc & 0x80) == (c & 0x80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rc & 0x20) == 0x20) { /* DQ5 =? '1' */
+ READ_CHAR(FLASH_BASE_ADDRESS +
+ offset + 3, &rc);
+ if ((rc & 0x80) == (c & 0x80))
+ break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ break;
+ case 2: /* Split the 32 bit write into two 8/16 bit Writings
+ (16bit width). */
+ if (FLASH_MODE == X16) {
+ FirstData = 0xaa; /* Data for the First Cycle */
+ SecondData = 0x55; /* Data for the Second Cycle */
+ ThirdData = 0xa0; /* Data for the Third Cycle */
+ FirstAddr = 0x5555; /* Address for the First Cycle */
+ SecondAddr = 0x2aaa; /* Address for the Second Cycle */
+ ThirdAddr = 0x5555; /* Address for the Third Cycle */
+ } else { /* if (FLASH_MODE == 8) */
+
+ FirstData = 0xaaaa; /* Data for the First Cycle */
+ SecondData = 0x5555; /* Data for the Second Cycle */
+ ThirdData = 0xa0a0; /* Data for the Third Cycle */
+ FirstAddr = 0xaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x5555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaa; /* Address for the Third Cycle */
+ }
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+#ifdef BE
+ s = (data >> 16);
+#else
+ s = data;
+#endif
+ WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s);
+ /* Writing Two Bytes */
+ if (FLASH_MODE == X16) {
+ data80 = 0x80;;
+ data20 = 0x20;;
+ } else { /* if (FLASH_MODE == 8) */
+
+ data80 = 0x8080;
+ data20 = 0x2020;
+ }
+ while (true) {
+ READ_SHORT(FLASH_BASE_ADDRESS + offset,
+ &rs);
+ if ((rs & data80) == (s & data80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rs & data20) == data20) { /* DQ5 =? DATA */
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ offset, &rs);
+ if ((rs & data80) == (s & data80))
+ break; /* DQ7 = DATA */
+ else {
+ flashReset();
+ return false; /* DQ7 != DATA */
+ }
+ }
+ }
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ FirstAddr * FLASH_WIDTH, FirstData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH, SecondData);
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH, ThirdData);
+#ifdef BE
+ s = data;
+#else
+ s = (data >> 16);
+#endif
+ WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s);
+ /* Writing Two Bytes */
+ while (true) {
+ READ_SHORT(FLASH_BASE_ADDRESS + offset + 2,
+ &rs);
+ if ((rs & data80) == (s & data80)) /* DQ7 =? DATA */
+ break; /* DQ7 = DATA */
+ if ((rs & data20) == data20) { /* DQ5 =? '1' */
+ READ_SHORT(FLASH_BASE_ADDRESS +
+ offset + 2, &rs);
+ if ((rs & data80) == (s & data80))
+ break; /* DQ7 = DATA */
+ else {
+ flashReset();
+ return false; /* DQ7 != DATA */
+ }
+ }
+ }
+ return true;
+ case 4:
+ case 8:
+ if (FLASH_MODE == X16) {
+ FirstData = 0x00aa00aa;
+ SecondData = 0x00550055;
+ ThirdData = 0x00a000a0;
+ FirstAddr = 0x5555;
+ SecondAddr = 0x2aaa;
+ ThirdAddr = 0x5555;
+ } else { /* (FLASH_MODE == 8) */
+
+ FirstData = 0xaaaaaaaa; /* Data for the First Cycle */
+ SecondData = 0x55555555; /* Data for the Second Cycle */
+ ThirdData = 0xa0a0a0a0; /* Data for the Third Cycle */
+ FirstAddr = 0xaaaaaaaa; /* Address for the First Cycle */
+ SecondAddr = 0x55555555; /* Address for the Second Cycle */
+ ThirdAddr = 0xaaaaaaaa; /* Address for the Third Cycle */
+ }
+ WRITE_WORD(FLASH_BASE_ADDRESS + FirstAddr *
+ FLASH_WIDTH + offset % FLASH_WIDTH,
+ FirstData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ SecondAddr * FLASH_WIDTH +
+ offset % FLASH_WIDTH, SecondData);
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ ThirdAddr * FLASH_WIDTH +
+ offset % FLASH_WIDTH, ThirdData);
+ /* writting the word. */
+ WRITE_WORD(FLASH_BASE_ADDRESS + offset, data);
+ /* preparing the polling patterns. */
+ if (FLASH_MODE == X16) {
+ data80 = 0x00800080;
+ data20 = 0x00200020;
+ } else { /* (FLASH_MODE == 8) */
+
+ data80 = 0x80808080;
+ data20 = 0x20202020;
+ }
+ while (true) { /* polling loop. */
+ rw = READWORD(FLASH_BASE_ADDRESS + offset);
+ /* DQ7 =? DATA */
+ if ((rw & data80) == (data & data80))
+ break; /* DQ7 = DATA */
+ if ((rw & data20) == data20) { /* DQ5 =? '1' */
+ rw =
+ READWORD(FLASH_BASE_ADDRESS +
+ offset);
+ if ((rw & data80) ==
+ (data & data80)) break; /* DQ7 = DATA */
+ else
+ return false; /* DQ7 != DATA */
+ }
+ }
+ return true;
+ default:
+ return false; /* case of invalid flash Width. */
+ }
+ } else { /* Intel/Micron */
+
+ switch (FLASH_WIDTH) {
+ case 1:
+ /* Writing First Byte */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x10);
+#ifdef BE
+ c = (data >> 24);
+#else
+ c = data;
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset, c);
+ while (true) {
+ /* Reading STATUS Register */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & 0x80) == 0x80)
+ break; /* Case of Write-Operation had Ended */
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & 0x10) == 0x10)
+ return false; /* Write failure */
+
+ /* Writing Second Byte */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x10);
+#ifdef BE
+ c = (data >> 16);
+#else
+ c = (data >> 8);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 1, c);
+ while (true) {
+ /* Reading STATUS Register */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70);
+ regValue =
+ READCHAR(FLASH_BASE_ADDRESS + 1);
+ if ((regValue & 0x80) == 0x80)
+ break; /* Write operation ended */
+ }
+ /* Reading STATUS Register for Writing verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 1, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS + 1);
+ if ((regValue & 0x10) == 0x10)
+ return false; /* Write failure */
+
+ /* Writing Third Byte */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x10);
+#ifdef BE
+ c = (data >> 8);
+#else
+ c = (data >> 16);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 2, c);
+ while (true) {
+ /* Reading STATUS Register */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70);
+ regValue =
+ READCHAR(FLASH_BASE_ADDRESS + 2);
+ if ((regValue & 0x80) == 0x80)
+ break; /* Write operation ended */
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 2, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS + 2);
+ if ((regValue & 0x10) == 0x10)
+ return false; /* Write failure */
+
+ /* Writing Fourth Byte */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x10);
+#ifdef BE
+ c = data;
+#else
+ c = (data >> 24);
+#endif
+ WRITE_CHAR(FLASH_BASE_ADDRESS + offset + 3, c);
+ while (true) {
+ /* Reading STATUS Register */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70);
+ regValue =
+ READCHAR(FLASH_BASE_ADDRESS + 3);
+ if ((regValue & 0x80) == 0x80)
+ break; /* Write operation ended */
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS + 3, 0x70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS + 3);
+ if ((regValue & 0x10) == 0x10)
+ return false; /* Write failure */
+ flashReset();
+ return true;
+ case 2:
+ if (FLASH_MODE == X16) { /* Case of one X16 bit device */
+ FirstData = 0x0010; /* Data for the First Cycle */
+ } else { /* if (FLASH_MODE == 8) ==> Case of two X8 bit devices */
+
+ FirstData = 0x1010; /* Data for the First Cycle */
+ }
+ /* Writing First two Bytes */
+ WRITE_SHORT(FLASH_BASE_ADDRESS, FirstData);
+#ifdef BE
+ s = (data >> 16);
+#else
+ s = data;
+#endif
+ WRITE_SHORT(FLASH_BASE_ADDRESS + offset, s);
+ if (FLASH_MODE == X16) {
+ data70 = 0x0070;
+ data80 = 0x0080;
+ data10 = 0x0010;
+ } else { /* case of (FLASH_MODE == X8) */
+
+ data70 = 0x7070;
+ data80 = 0x8080;
+ data10 = 0x1010;
+ }
+ /* polling on writing action => when done break. */
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS, data70);
+ regValue = READSHORT(FLASH_BASE_ADDRESS);
+ if ((regValue & data80) == data80)
+ break;
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & data10) == data10)
+ return false; /* Write failure */
+ /* Writing Last two Bytes */
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 2, FirstData);
+#ifdef BE
+ s = data;
+#else
+ s = (data >> 16);
+#endif
+ WRITE_SHORT(FLASH_BASE_ADDRESS + offset + 2, s);
+ /* polling on writing action => when done break. */
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS + 2,
+ data70);
+ regValue =
+ READSHORT(FLASH_BASE_ADDRESS + 2);
+ if ((regValue & data80) == data80)
+ break;
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & data10) == data10)
+ return false; /* Write failure */
+ flashReset();
+ return true;
+ case 4:
+ case 8:
+ if (FLASH_MODE == X16) { /* Case of one X16 bit device */
+ FirstData = 0x00100010; /* Data for the First Cycle */
+ } else { /* (FLASH_MODE == 8) ==> Case of two X8 bit devices */
+
+ FirstData = 0x10101010; /* Data for the First Cycle */
+ }
+ /* Writing First two Bytes */
+ WRITE_WORD(FLASH_BASE_ADDRESS +
+ offset % FLASH_WIDTH, FirstData);
+#ifdef BE
+ s = (data >> 16);
+#else
+ s = data;
+#endif
+ /* writing the 32-bit data to flash. */
+ WRITE_WORD(FLASH_BASE_ADDRESS + offset, data);
+ if (FLASH_MODE == X16) {
+ data70 = 0x0070;
+ data80 = 0x0080;
+ data10 = 0x0010;
+ } else { /* (FLASH_MODE == 8) */
+
+ data70 = 0x7070;
+ data80 = 0x8080;
+ data10 = 0x1010;
+ }
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ offset % FLASH_WIDTH, data70);
+ regValue = READSHORT(FLASH_BASE_ADDRESS);
+ if ((regValue & data80) == data80)
+ break;
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & data10) == data10)
+ return false; /* Write failure */
+
+ /* Writing Last two Bytes */
+#ifdef BE
+ s = data;
+#else
+ s = (data >> 16);
+#endif
+ while (true) {
+ WRITE_SHORT(FLASH_BASE_ADDRESS +
+ offset % FLASH_WIDTH + 2,
+ data70);
+ regValue =
+ READSHORT(FLASH_BASE_ADDRESS +
+ offset % FLASH_WIDTH + 2);
+ if ((regValue & data80) == data80)
+ break;
+ }
+ /* Reading STATUS Register for Writing Verification */
+ WRITE_CHAR(FLASH_BASE_ADDRESS, data70);
+ regValue = READCHAR(FLASH_BASE_ADDRESS);
+ if ((regValue & data10) == data10)
+ return false; /* Write failure */
+
+ flashReset();
+ return true;
+ default:
+ flashReset();
+ return false;
+ }
+ }
+ flashReset();
+ return true;
+}
+
+/********************************************************************
+* flashReadWord - Read 32Bit from the FLASH memory at a given offset
+* from the FLASH base address.
+* address 0 = 0x00000000 !!
+* The function takes care of Big/Little endian conversion
+* INPUTS: offset,the offset from the flash`s base address
+* RETURNS: data
+*********************************************************************/
+unsigned int flashReadWord(unsigned int offset)
+{
+ unsigned int regValue;
+ flashReset();
+ READ_WORD(FLASH_BASE_ADDRESS + offset, &regValue);
+ return regValue;
+}
+
+/********************************************************************
+* flashInWhichSector - Returns the sector`s number at which offset is at.
+*
+* INPUTS: Offset
+* RETURNS: Sector number,or 0xffffffff in case the address is out of range or
+* flash wasn't initialize.
+*********************************************************************/
+unsigned int flashInWhichSector(unsigned int offset)
+{
+ unsigned int sectorNumber, numberOfDevices;
+ unsigned int accMemory = 0;
+
+ if ((FLASH_MODE == PURE8) || (FLASH_MODE == X8)) {
+ numberOfDevices = FLASH_WIDTH;
+ } else { /* X16 mode */
+
+ numberOfDevices = FLASH_WIDTH / 2;
+ }
+ for (sectorNumber = 0;
+ sectorNumber < flashTypes[NUMBER_OF_SECTORS]; sectorNumber++) {
+ accMemory =
+ accMemory + flashTypes[FIRST_SECTOR_SIZE +
+ sectorNumber];
+ if (offset < accMemory * numberOfDevices * 1024)
+ return sectorNumber;
+ }
+ return 0xffffffff;
+}
+
+/********************************************************************
+* flashGetSectorSize - When given a Valid sector Number returns its Size.
+*
+* INPUTS: unsigned int sectorNumber.
+* RETURNS: Sector size. (if Sector number isn't valid or flash wasn't
+* initialize return 0.)
+*********************************************************************/
+unsigned int flashGetSectorSize(unsigned int sectorNumber)
+{
+ if (sectorNumber >= flashTypes[NUMBER_OF_SECTORS])
+ return 0;
+ else {
+ if (FLASH_MODE != PURE8)
+ return (flashTypes
+ [FIRST_SECTOR_SIZE +
+ sectorNumber] * _1K * (FLASH_WIDTH * 8 /
+ FLASH_MODE));
+ else /* in case of PUR8 */
+ return (flashTypes
+ [FIRST_SECTOR_SIZE +
+ sectorNumber] * _1K * FLASH_WIDTH);
+ }
+}
+
+/********************************************************************
+* getFlashSize - Return Total flash size.
+*
+* INPUTS: N/A.
+* RETURNS: Flash size. (If flash wasn't initialize return 0)
+*********************************************************************/
+unsigned int flashGetSize()
+{
+ unsigned int sectorNum;
+ unsigned int totalSize = 0;
+
+ if (POINTER_TO_FLASH == 0)
+ return 0; /* case of flash not initialize */
+ for (sectorNum = 0; sectorNum < flashTypes[NUMBER_OF_SECTORS];
+ sectorNum++) {
+ totalSize += flashGetSectorSize(sectorNum);
+ }
+ return (totalSize);
+
+}
+
+/********************************************************************
+* flashGetSectorOffset - Returns sector base address.
+*
+* INPUTS: unsigned int sectorNum.
+* RETURNS: Sector Base Address.
+*********************************************************************/
+unsigned int flashGetSectorOffset(unsigned int sectorNum)
+{
+ unsigned int i;
+ unsigned int sectorBaseAddress = 0;
+ unsigned int numOfDevices;
+
+ if (sectorNum > (flashParametrs[NUMBER_OF_SECTORS] - 1))
+ return 0xffffffff;
+ for (i = 0; i < sectorNum; i++) {
+ sectorBaseAddress =
+ sectorBaseAddress + flashTypes[FIRST_SECTOR_SIZE + i];
+ }
+ if (FLASH_MODE == X16)
+ numOfDevices = FLASH_WIDTH * 8 / FLASH_MODE;
+ else
+ numOfDevices = FLASH_WIDTH;
+ return (_1K * sectorBaseAddress * numOfDevices);
+
+}
+
+/********************************************************************
+* flashWriteBlock - Write block of chars to flash.
+*
+* INPUTS: unsigned int offset - flash destination address.
+* unsigned int numOfByte - block size.
+* unsigned char * blockAddress - block source address.
+* RETURNS: Number of Bytes written.
+*********************************************************************/
+unsigned int flashWriteBlock(unsigned int offset, unsigned int numOfByte,
+ unsigned char *blockAddress)
+{
+ register unsigned int flashWrite;
+ register unsigned int align;
+ register unsigned int num;
+ register unsigned int i;
+
+ if ((offset + numOfByte) > flashGetSize())
+ numOfByte = flashGetSize() - offset; /* getting to flash boundary. */
+ num = numOfByte;
+ align = offset % 4; /* alignment toward flash. */
+ /* writes chars until the offset toward flash will be align. */
+ for (i = align; (i < 4) && (numOfByte > 0) && (align != 0); i++) {
+ flashWriteChar(offset, blockAddress[0]);
+ numOfByte--;
+ offset++;
+ blockAddress++;
+ }
+ while (numOfByte > 3) {
+#ifdef LE
+ flashWrite = blockAddress[0] | (blockAddress[1] << 8) |
+ (blockAddress[2] << 16) | (blockAddress[3] << 24);
+#else
+ flashWrite = blockAddress[3] | (blockAddress[2] << 8) |
+ (blockAddress[1] << 16) | (blockAddress[0] << 24);
+#endif
+ if (flashWrite != 0xffffffff) /* for optimization. */
+ flashWriteWord(offset, flashWrite);
+ numOfByte -= 4;
+ blockAddress += 4;
+ offset += 4;
+ }
+ while (numOfByte > 0) {
+ flashWriteChar(offset, blockAddress[0]);
+ numOfByte--;
+ blockAddress++;
+ offset++;
+ }
+ return num;
+}
+
+/********************************************************************
+* flashReadBlock - Read block of chars from flash.
+*
+* INPUTS: unsigned int offset - flash source address.
+* unsigned int numOfByte - block size.
+* unsigned char * blockAddress - block destination address.
+* RETURNS: Number of Bytes written.
+*********************************************************************/
+unsigned int flashReadBlock(unsigned int offset, unsigned int numOfByte,
+ unsigned char *blockAddress)
+{
+ unsigned int i;
+ for (i = 0; i < numOfByte; i++) {
+ blockAddress[i] = flashReadChar(offset + i);
+ }
+ return numOfByte;
+}
+
+/********************************************************************
+* flashReadChar - read one charecter form given flash offset.
+*
+* INPUTS: unsigned int offset - required offset to be read from.
+* RETURNS: read charecter.
+*********************************************************************/
+unsigned char flashReadChar(unsigned int offset)
+{
+ unsigned char regValue;
+
+ flashReset();
+ READ_CHAR(FLASH_BASE_ADDRESS + offset, &regValue);
+ return regValue;
+}
+
+/********************************************************************
+* flashReadShort - read 16bit form given flash offset.
+*
+* INPUTS: unsigned int offset - required offset to be read from.
+* RETURNS: 16bit data.
+*********************************************************************/
+unsigned short flashReadShort(unsigned int offset)
+{
+ unsigned short regValue;
+
+ flashReset();
+ READ_SHORT(FLASH_BASE_ADDRESS + offset, &regValue);
+ return regValue;
+}
+
+/********************************************************************
+* flashWriteShort - write 16bit data to a given flash offset.
+* It reads the whole word 32bit wide, modify the short
+* and write back the word.
+*
+* INPUTS: unsigned int offset - required offset to be write to.
+* unsigned short sdata - data to be written.
+* RETURNS: true if writting successesed false otherwise.
+*********************************************************************/
+bool flashWriteShort(unsigned int offset, unsigned short sdata)
+{
+ unsigned int align;
+ unsigned int flashWrite;
+ unsigned int flashRead;
+
+ align = offset % 4;
+ if ((align == 1) || (align == 3))
+ return false; /* offset misaligned. */
+ flashRead = flashReadWord(offset - align);
+ if (align == 0)
+#ifdef BE
+ flashWrite = (flashRead & 0x0000ffff) | (sdata << 16);
+#else
+ flashWrite = (flashRead & 0xffff0000) | sdata;
+#endif
+ else /* (align == 2) */
+#ifdef BE
+ flashWrite = (flashRead & 0xffff0000) | sdata;
+#else
+ flashWrite = (flashRead & 0x0000ffff) | (sdata << 16);
+#endif
+ flashWriteWord(offset - align, flashWrite);
+ return true;
+
+}
+
+/********************************************************************
+* flashWriteChar - write one charecter (8 bit) to a given flash offset.
+* It reads the whole word 32bit wide, modify the charecter
+* and write back the word.
+*
+* INPUTS: unsigned int offset - required offset to be write to.
+* unsigned short sdata - data to be written.
+* RETURNS: true if writting successed.
+*********************************************************************/
+bool flashWriteChar(unsigned int offset, unsigned char cdata)
+{
+ unsigned int align;
+ unsigned int flashWrite;
+ unsigned int flashRead;
+
+ align = offset % 4;
+ flashRead = flashReadWord(offset - align);
+#ifdef BE
+ flashWrite = (flashRead & ~(0xff000000 >> (8 * align))) |
+ (cdata << (8 * (3 - align)));
+#else
+ flashWrite = (flashRead & ~(0xff000000 << (8 * align))) |
+ (cdata << (8 * align));
+#endif
+ flashWriteWord(offset - align, flashWrite);
+ return true;
+}
+
+/********************************************************************
+* flashGetNumOfSectors - write one charecter (8 bit) to a given flash offset.
+* It reads the whole word 32bit wide, modify the
+* charecter and write back the word.
+*
+* INPUTS: N/A.
+* RETURNS: Number of sectors.
+*********************************************************************/
+unsigned int flashGetNumOfSectors(void)
+{
+ return (flashTypes[NUMBER_OF_SECTORS]);
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h b/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h
new file mode 100644
index 000000000..a565ce72a
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/galileo_port.h
@@ -0,0 +1,8 @@
+#define GFP_KERNEL 0
+#define GFP_ATOMIC 1
+#define KERN_ERR ""
+
+void *kmalloc(unsigned int, int);
+void *memset(void *, char, unsigned int);
+int memcmp(char *, char *, unsigned int);
+void *memcpy(void *to, const void *from, unsigned int);
diff --git a/arch/mips/galileo-boards/ev64120/compressed/gt64011.h b/arch/mips/galileo-boards/ev64120/compressed/gt64011.h
new file mode 100644
index 000000000..94e012c76
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/gt64011.h
@@ -0,0 +1,279 @@
+/*
+ * gt64011.h: Galileo PCI system controller
+ * Copyright (c) 1998 Algorithmics Ltd
+ */
+
+#ifdef __ASSEMBLER__
+
+/* offsets from base register */
+#define GT64011(x) (x)
+
+/* device is littleendian, so data may need to be swapped */
+#ifdef GALILEO_PORT
+#define htoll(x) ((((x) & 0x00ff) << 24) | \
+ (((x) & 0xff00) << 8) | \
+ (((x) >> 8) & 0xff00) | \
+ (((x) >> 24) & 0x00ff))
+/*#define ltohl(x) htoll(x)*/
+#else
+#define htoll(x) (x)
+/* #define ltohl(x) (x) */
+#endif
+
+#else /* !__ASSEMBLER */
+
+/* offsets from base pointer, this construct allows optimisation */
+static char *const _gt64011p = (char *) PA_TO_KVA1(GT64011_BASE);
+
+#define GT64011(x) *(volatile unsigned long *)(_gt64011p + (x))
+
+/* device is littleendian, so data may need to be swapped */
+#ifdef GALILEO_PORT
+#define htoll(x) ({ \
+ unsigned int v = (unsigned int)(x); \
+ v = (((v & 0x00ff) << 24) | \
+ ((v & 0xff00) << 8) | \
+ ((v >> 8) & 0xff00) | \
+ ((v >> 24) & 0x00ff)); \
+ v; \
+ })
+#define ltohl(x) htoll(x)
+
+#else
+asjdsajd
+#define htoll(x) (x)
+#define ltohl(x) (x)
+#endif
+#endif /* __ASSEMBLER__ */
+/* CPU configuration */
+#define GT_CPU_CFG GT64011(0x000)
+#define GT_CPU_CFG_WriteMode (1<<11)
+#define GT_CPU_CFG_Endianess (1<<12)
+/* Processor Address Space */
+#define GT_PAS_RAS10LO GT64011(0x008)
+#define GT_PAS_RAS10HI GT64011(0x010)
+#define GT_PAS_RAS32LO GT64011(0x018)
+#define GT_PAS_RAS32HI GT64011(0x020)
+#define GT_PAS_CS20LO GT64011(0x028)
+#define GT_PAS_CS20HI GT64011(0x030)
+#define GT_PAS_CS3BOOTLO GT64011(0x038)
+#define GT_PAS_CS3BOOTHI GT64011(0x040)
+#define GT_PAS_PCIIOLO GT64011(0x048)
+#define GT_PAS_PCIIOHI GT64011(0x050)
+#define GT_PAS_PCIMEMLO GT64011(0x058)
+#define GT_PAS_PCIMEMHI GT64011(0x060)
+#define GT_PAS_INTDEC GT64011(0x068)
+#define GT_PAS_BUSERRLO GT64011(0x070)
+#define GT_PAS_PCIMEM1LO GT64011(0x080)
+#define GT_PAS_PCIMEM1HI GT64011(0x088)
+#define GT_PAS_LOMASK_Low 0x7ff
+#define GT_PAS_LOSHIFT_Low 0
+#define GT_PAS_HIMASK_High 0x07f
+#define GT_PAS_HISHIFT_High 0
+/* DRAM and Device Address Space */
+#define GT_DDAS_RAS0LO GT64011(0x400)
+#define GT_DDAS_RAS0HI GT64011(0x404)
+#define GT_DDAS_RAS1LO GT64011(0x408)
+#define GT_DDAS_RAS1HI GT64011(0x40c)
+#define GT_DDAS_RAS2LO GT64011(0x410)
+#define GT_DDAS_RAS2HI GT64011(0x414)
+#define GT_DDAS_RAS3LO GT64011(0x418)
+#define GT_DDAS_RAS3HI GT64011(0x41c)
+#define GT_DDAS_CS0LO GT64011(0x420)
+#define GT_DDAS_CS0HI GT64011(0x424)
+#define GT_DDAS_CS1LO GT64011(0x428)
+#define GT_DDAS_CS1HI GT64011(0x42c)
+#define GT_DDAS_CS2LO GT64011(0x430)
+#define GT_DDAS_CS2HI GT64011(0x434)
+#define GT_DDAS_CS3LO GT64011(0x438)
+#define GT_DDAS_CS3HI GT64011(0x43c)
+#define GT_DDAS_BOOTCSLO GT64011(0x440)
+#define GT_DDAS_BOOTCSHI GT64011(0x444)
+#define GT_DDAS_ERROR GT64011(0x470)
+#define GT_DDAS_LOMASK_Low 0xff
+#define GT_DDAS_LOSHIFT_Low 0
+#define GT_DDAS_HIMASK_High 0xff
+#define GT_DDAS_HISHIFT_High 0
+/* DRAM Configuration */
+#define GT_DRAM_CFG GT64011(0x448)
+#define GT_DRAM_CFG_RefIntCntMASK 0x00003fff
+#define GT_DRAM_CFG_RefIntCntSHIFT 0
+#define GT_DRAM_CFG_RefIntCnt(x) (((x)<<GT_DRAM_CFG_RefIntCntSHIFT)&\
+ GT_DRAM_CFG_RefIntCntMASK)
+#define GT_DRAM_CFG_StagRef (1<<16)
+#define GT_DRAM_CFG_StagRefOn 0
+#define GT_DRAM_CFG_StagRefAll GT_DRAM_CFG_StagRef
+#define GT_DRAM_CFG_ADSFunct (1<<17)
+#define GT_DRAM_CFG_ADSFunctDRAM 0
+#define GT_DRAM_CFG_ADSFunctOnly GT_DRAM_CFG_ADSFunct
+#define GT_DRAM_CFG_DRAMLatch (1<<18)
+#define GT_DRAM_CFG_DRAMLatchActive 0
+#define GT_DRAM_CFG_DRAMLatchTransparent GT_DRAM_CFG_DRAMLatch
+/* DRAM Parameters */
+#define GT_DRAMPAR_BANK0 GT64011(0x44c)
+#define GT_DRAMPAR_BANK1 GT64011(0x450)
+#define GT_DRAMPAR_BANK2 GT64011(0x454)
+#define GT_DRAMPAR_BANK3 GT64011(0x458)
+#define GT_DRAMPAR_CASWr (1<<0)
+#define GT_DRAMPAR_CASWr1 0
+#define GT_DRAMPAR_CASWr2 GT_DRAMPAR_CASWr
+#define GT_DRAMPAR_RAStoCASWr (1<<1)
+#define GT_DRAMPAR_RAStoCASWr2 0
+#define GT_DRAMPAR_RAStoCASWr3 GT_DRAMPAR_RAStoCASWr
+#define GT_DRAMPAR_CASRd (1<<2)
+#define GT_DRAMPAR_CASRd1 0
+#define GT_DRAMPAR_CASRd2 GT_DRAMPAR_CASRd
+#define GT_DRAMPAR_RAStoCASRd (1<<3)
+#define GT_DRAMPAR_RAStoCASRd2 0
+#define GT_DRAMPAR_RAStoCASRd3 GT_DRAMPAR_RAStoCASRd
+#define GT_DRAMPAR_RefreshSHIFT 4
+#define GT_DRAMPAR_RefreshMASK (3<<4)
+#define GT_DRAMPAR_Refresh512 (0<<4)
+#define GT_DRAMPAR_Refresh1024 (1<<4)
+#define GT_DRAMPAR_Refresh2048 (2<<4)
+#define GT_DRAMPAR_Refresh4096 (3<<4)
+#define GT_DRAMPAR_BankWidth (1<<6)
+#define GT_DRAMPAR_BankWidth32 0
+#define GT_DRAMPAR_BankWidth64 GT_DRAMPAR_BankWidth
+#define GT_DRAMPAR_BankLoc (1<<7)
+#define GT_DRAMPAR_BankLocEven 0
+#define GT_DRAMPAR_BankLocOdd GT_DRAMPAR_BankLoc
+#define GT_DRAMPAR_Parity (1<<8)
+#define GT_DRAMPAR_ParityDisable 0
+#define GT_DRAMPAR_ParityEnable GT_DRAMPAR_Parity
+#define GT_DRAMPAR_MBZ (1<<9)
+/* Device Parameters */
+#define GT_DEVPAR_BANK0 GT64011(0x45c)
+#define GT_DEVPAR_BANK1 GT64011(0x460)
+#define GT_DEVPAR_BANK2 GT64011(0x464)
+#define GT_DEVPAR_BANK3 GT64011(0x468)
+#define GT_DEVPAR_BOOT GT64011(0x46c)
+#define GT_DEVPAR_TurnOffMASK (7<<0)
+#define GT_DEVPAR_TurnOffSHIFT 0
+#define GT_DEVPAR_TurnOff(x) ((x)<<0)
+#define GT_DEVPAR_AccToFirstMASK (15<<3)
+#define GT_DEVPAR_AccToFirstSHIFT 3
+#define GT_DEVPAR_AccToFirst(x) ((x)<<3)
+#define GT_DEVPAR_AccToNextMASK (15<<7)
+#define GT_DEVPAR_AccToNextSHIFT 7
+#define GT_DEVPAR_AccToNext(x) ((x)<<7)
+#define GT_DEVPAR_ADStoWrMASK (7<<11)
+#define GT_DEVPAR_ADStoWrSHIFT 11
+#define GT_DEVPAR_ADStoWr(x) ((x)<<11)
+#define GT_DEVPAR_WrActiveMASK (7<<14)
+#define GT_DEVPAR_WrActiveSHIFT 14
+#define GT_DEVPAR_WrActive(x) ((x)<<14)
+#define GT_DEVPAR_WrHighMASK (7<<17)
+#define GT_DEVPAR_WrHighSHIFT 17
+#define GT_DEVPAR_WrHigh(x) ((x)<<17)
+#define GT_DEVPAR_DevWidthMASK (3<<20)
+#define GT_DEVPAR_DevWidthSHIFT 20
+#define GT_DEVPAR_DevWidth8 (0<<20)
+#define GT_DEVPAR_DevWidth16 (1<<20)
+#define GT_DEVPAR_DevWidth32 (2<<20)
+#define GT_DEVPAR_DevWidth64 (3<<20)
+#define GT_DEVPAR_DevLoc (1<<23)
+#define GT_DEVPAR_DevLocEven 0
+#define GT_DEVPAR_DevLocOdd GT_DEVPAR_DevLoc
+#define GT_DEVPAR_LatchFunct (1<<25)
+#define GT_DEVPAR_LatchFunctTransparent 0
+#define GT_DEVPAR_LatchFunctEnable GT_DEVPAR_LatchFunct
+#define GT_DEVPAR_Parity (1<<30)
+#define GT_DEVPAR_ParityDisable 0
+#define GT_DEVPAR_ParityEnable GT_DEVPAR_Parity
+#define GT_DEVPAR_ReservedMASK 0x3d400000
+#define GT_DEVPAR_Reserved 0x14400000
+/* PCI Internal */
+#define GT_IPCI_CMD GT64011(0xc00)
+#define GT_IPCI_CMD_ByteSwap (1<<0)
+#define GT_IPCI_CMD_ByteSwapOn 0
+#define GT_IPCI_CMD_ByteSwapOff GT_INTPCI_CMD_ByteSwap
+#define GT_IPCI_CMD_SyncModeMASK (3<<1)
+#define GT_IPCI_CMD_SyncModeSHIFT 1
+#define GT_IPCI_CMD_SyncModeStd (0<<1)
+#define GT_IPCI_CMD_SyncMode1 (1<<1)
+#define GT_IPCI_CMD_SyncMode2 (2<<1)
+#define GT_IPCI_TOR GT64011(0xc04)
+#define GT_IPCI_TOR_Timeout0MASK (255<<0)
+#define GT_IPCI_TOR_Timeout0SHIFT 0
+#define GT_IPCI_TOR_Timeout0(x) ((x)<<0)
+#define GT_IPCI_TOR_Timeout1MASK (255<<8)
+#define GT_IPCI_TOR_Timeout1SHIFT 8
+#define GT_IPCI_TOR_Timeout1(x) ((x)<<8)
+#define GT_IPCI_TOR_RetryCtrMASK (255<<16)
+#define GT_IPCI_TOR_RetryCtrSHIFT 16
+#define GT_IPCI_TOR_RetryCtr(x) ((x)<<16)
+#define GT_IPCI_RAS10SIZE GT64011(0xc08)
+#define GT_IPCI_RAS32SIZE GT64011(0xc0c)
+#define GT_IPCI_CS20SIZE GT64011(0xc10)
+#define GT_IPCI_CS3BOOTSIZE GT64011(0xc14)
+#define GT_IPCI_SIZE_BankSizeMASK (0xfffff<<12)
+#define GT_IPCI_SIZE_BankSizeSHIFT 12
+#define GT_IPCI_INTRCAUSE GT64011(0xc18)
+#define GT_IPCI_INTRMASK GT64011(0xc1c)
+#define GT_INTR_INTSUM 0x0000001
+#define GT_INTR_MEMOUT 0x0000002
+#define GT_INTR_DMAOUT 0x0000004
+#define GT_INTR_CPUOUT 0x0000008
+#define GT_INTR_DMA0COMP 0x0000010
+#define GT_INTR_DMA1COMP 0x0000020
+#define GT_INTR_DMA2COMP 0x0000040
+#define GT_INTR_DMA3COMP 0x0000080
+#define GT_INTR_T0EXP 0x0000100
+#define GT_INTR_T1EXP 0x0000200
+#define GT_INTR_T2EXP 0x0000400
+#define GT_INTR_T3EXP 0x0000800
+#define GT_INTR_MASRDERR 0x0001000
+#define GT_INTR_SLVWRERR 0x0002000
+#define GT_INTR_MASWRERR 0x0004000
+#define GT_INTR_SLVRDERR 0x0008000
+#define GT_INTR_ADDRERR 0x0010000
+#define GT_INTR_MEMERR 0x0020000
+#define GT_INTR_MASABORT 0x0040000
+#define GT_INTR_TARABORT 0x0080000
+#define GT_INTR_RETRYCTR 0x0010000
+#define GT_INTR_CPU2PCIA 0x0020000
+#define GT_INTR_CPU2PCIB 0x0040000
+#define GT_INTR_CPU2PCIC 0x0080000
+#define GT_INTR_CPU2PCID 0x0100000
+#define GT_INTR_CPU2PCIE 0x0200000
+#define GT_INTR_PCI2CPUA 0x0400000
+#define GT_INTR_PCI2CPUB 0x0800000
+#define GT_INTR_PCI2CPUC 0x1000000
+#define GT_INTR_PCI2CPUD 0x2000000
+#define GT_INTR_CPUINTSUM 0x4000000
+#define GT_INTR_PCIINTSUM 0x8000000
+#define GT_IPCI_PCIINTMASK GT64011(0xc24)
+#define GT_IPCI_SERMASK GT64011(0xc28)
+#define GT_IPCI_SERMASK_AddrErr (1<<0)
+#define GT_IPCI_SERMASK_MasWrErr (1<<1)
+#define GT_IPCI_SERMASK_MasRdErr (1<<2)
+#define GT_IPCI_SERMASK_MemErr (1<<3)
+#define GT_IPCI_SERMASK_MasAbort (1<<4)
+#define GT_IPCI_SERMASK_TarAbort (1<<5)
+#define GT_IPCI_INTACK GT64011(0xc34)
+#define GT_IPCI_BAREN GT64011(0xc3c)
+#define GT_IPCI_BAREN_SwCs3BootDis (1<<0)
+#define GT_IPCI_BAREN_SwRas32Dis (1<<1)
+#define GT_IPCI_BAREN_SwRas10Dis (1<<2)
+#define GT_IPCI_BAREN_IntIODis (1<<3)
+#define GT_IPCI_BAREN_IntMemDis (1<<4)
+#define GT_IPCI_BAREN_Cs3BootDis (1<<5)
+#define GT_IPCI_BAREN_Cs20Dis (1<<6)
+#define GT_IPCI_BAREN_Ras32Dis (1<<7)
+#define GT_IPCI_BAREN_Ras10Dis (1<<8)
+#define GT_IPCI_CFGADDR GT64011(0xcf8)
+#define GT_IPCI_CFGDATA GT64011(0xcfc)
+#define GT_IPCI_CFGADDR_RegNumMASK (0x3f<<2)
+#define GT_IPCI_CFGADDR_RegNumSHIFT 2
+#define GT_IPCI_CFGADDR_RegNum(x) ((x)<<2)
+#define GT_IPCI_CFGADDR_FunctNumMASK (0x7<<8)
+#define GT_IPCI_CFGADDR_FunctNumSHIFT 8
+#define GT_IPCI_CFGADDR_FunctNum(x) ((x)<<8)
+#define GT_IPCI_CFGADDR_DevNumMASK (0x1f<<11)
+#define GT_IPCI_CFGADDR_DevNumSHIFT 11
+#define GT_IPCI_CFGADDR_DevNum(x) ((x)<<11)
+#define GT_IPCI_CFGADDR_BusNumMASK (0xff<<16)
+#define GT_IPCI_CFGADDR_BusNumSHIFT 16
+#define GT_IPCI_CFGADDR_BusNum(x) ((x)<<16)
+#define GT_IPCI_CFGADDR_ConfigEn (1<<31)
diff --git a/arch/mips/galileo-boards/ev64120/compressed/head.S b/arch/mips/galileo-boards/ev64120/compressed/head.S
new file mode 100644
index 000000000..fcbe250e7
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/head.S
@@ -0,0 +1,19 @@
+/*
+ * arch/mips/galileo/compressed/head.S
+ *
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+
+ .text
+NESTED(startup, 16, sp)
+ .set noreorder
+
+ jal decompress_kernel
+ nop
+
+ jal kernel_location_start+0x584
+ nop
+
+ END(startup)
diff --git a/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal b/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal
new file mode 100644
index 000000000..68eda2a7c
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/ld.script.gal
@@ -0,0 +1,19 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(startup)
+SECTIONS
+{
+ kernel_location_start = 0x80100000;
+ . = 0x80400000;
+ .text : {
+ *(.text)
+ }
+ .bss : {
+ *(.bss)
+ }
+ .data :{
+ *(.data)
+ }
+ malloc_start = .;
+}
+
diff --git a/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash b/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash
new file mode 100644
index 000000000..1eef527b1
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash
@@ -0,0 +1,29 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(sbdreset)
+
+SECTIONS
+{
+ . = 0xBFC00000;
+ .got : {*(.got)}
+ .reset : {
+ sbdreset = ABSOLUTE(.);
+ sbdreset_evb64120A.o
+ evb64120A_Setup.o /* <-- Note: contains xfer.c contents as well.. */
+ pci_etherboot.o
+ memory.o
+ pci.o
+ }
+ kernel_location_start = 0x80100000;
+ . = 0x80400000;
+ .text : {
+ *(.text)
+ }
+ .bss : {
+ *(.bss)
+ }
+ .data :{
+ *(.data)
+ }
+ malloc_start = .;
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2 b/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2
new file mode 100644
index 000000000..d017e5f24
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.Flash2
@@ -0,0 +1,24 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(XferToRam)
+
+SECTIONS
+{
+ . = 0xBF000000;
+ .got : {*(.got)}
+ .reset : {
+ xfer.o
+ }
+ kernel_location_start = 0x80100000;
+ . = 0x80400000;
+ .text : {
+ *(.text)
+ }
+ .bss : {
+ *(.bss)
+ }
+ .data :{
+ *(.data)
+ }
+ malloc_start = .;
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner b/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner
new file mode 100644
index 000000000..77ebe571c
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/ld.sys.big.burner
@@ -0,0 +1,11 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(main)
+
+SECTIONS
+{
+ . = 0xA0400000;
+ .text : {*(.text)}
+ .data : {*(.data)}
+ .bss : {*(.bss)}
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/load.c b/arch/mips/galileo-boards/ev64120/compressed/load.c
new file mode 100644
index 000000000..e05dcb901
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/load.c
@@ -0,0 +1,244 @@
+
+/* control character used for download */
+#define ETX CNTRL('c')
+#define ACK CNTRL('f')
+#define NAK CNTRL('u')
+#define XON CNTRL('q')
+#define XOFF CNTRL('s')
+
+unsigned int csum;
+unsigned int dl_entry;
+
+static const unsigned char hextab[256] = {
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
+ 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255,
+};
+
+
+unsigned char ascii_to_bin(unsigned char c)
+{
+ return hextab[c];
+}
+
+unsigned char read_char_direct(void)
+{
+ unsigned char c, *cp;
+ cp = (unsigned char *) 0xbd000020;
+ while (1) {
+ if (*(cp + 0x14) & 0x01) {
+ c = (volatile unsigned char) *cp;
+ return c;
+ }
+ cp++;
+ cp--;
+ }
+}
+
+unsigned char get_pair(void)
+{
+ unsigned char byte;
+
+ byte = ascii_to_bin(read_char_direct()) << 4;
+ byte |= ascii_to_bin(read_char_direct());
+ csum += byte;
+ return (byte);
+}
+
+
+void serial_putc(int ch)
+{
+ unsigned long temp;
+ for (temp = 0; temp < 1000; temp++) {
+ }
+ *(char *) 0xbd000020 = (char) ch;
+}
+
+
+int inline serial_getc(void)
+{
+ return read_char_direct();
+}
+
+int serial_ischar(void)
+{
+
+ unsigned char c, *cp;
+ unsigned count;
+ cp = (unsigned char *) 0xbd000020;
+ count = 0;
+ while (count != 100) {
+ if (*(cp + 0x14) & 0x01) {
+ c = (volatile unsigned char) *cp;
+ return c;
+ }
+ cp++;
+ cp--;
+ count++;
+ }
+ return 0;
+}
+
+int serial_init(void)
+{
+ return 0;
+}
+
+
+int galileo_dl(void)
+{
+#define display_char '.'
+#define display_error 'E'
+#define display_error_bad_7 '7'
+#define display_error_unknown 'U'
+#define display_error_length 'L'
+
+ register int length, address, save_csum;
+ int i, first, done, eof, reccount, type, client_pc;
+ int src, dbl_length;
+ unsigned char *buffptr, databuff[258], tempo;
+ register int display_counter, chunks, leftovers, putter,
+ bytes_per_chunk;
+ display_counter = 0;
+ bytes_per_chunk = 16;
+ csum = 0;
+
+ reccount = 1;
+ for (first = 1, done = 0; !done; first = 0, reccount++) {
+ while (read_char_direct() != 'S')
+ continue;
+ csum = 0;
+ type = read_char_direct();
+ length = get_pair();
+ if (length < 0 || length >= 256) {
+ *(char *) 0xbd000020 = display_error_length;
+ // *(char*)0xbd00000c = display_error_length;
+ return 0;
+ }
+ length--;
+ switch (type) {
+ case '0':
+ while (length-- > 0)
+ get_pair();
+ break;
+ case '3':
+ address = 0;
+ for (i = 0; i < 4; i++) {
+ address <<= 8;
+ address |= get_pair();
+ length--;
+ }
+ if (address == -1) {
+ eof = 1;
+ continue;
+ }
+ buffptr = &databuff[0];
+ dbl_length = length << 1;
+ chunks = dbl_length / bytes_per_chunk;
+ leftovers = dbl_length % bytes_per_chunk;
+ putter = bytes_per_chunk >> 1;
+ while (chunks--) {
+ for (i = 0; i < bytes_per_chunk; i++)
+ databuff[i] = read_char_direct();
+ src = i = 0;
+ while (i++ < putter) {
+ tempo =
+ (ascii_to_bin(databuff[src++])
+ << 4) |
+ ascii_to_bin(databuff[src++]);
+ csum += tempo;
+ *(char *) address++ = tempo;
+ }
+ }
+ if (leftovers) {
+ putter = leftovers / 2;
+ for (i = 0; i < leftovers; i++)
+ databuff[i] = read_char_direct();
+ src = i = 0;
+ while (i++ < putter) {
+ tempo =
+ (ascii_to_bin(databuff[src++])
+ << 4) |
+ ascii_to_bin(databuff[src++]);
+ csum += tempo;
+ *(char *) address++ = tempo;
+ }
+ }
+ break;
+
+ case '7':
+ address = 0;
+ for (i = 0; i < 4; i++) {
+ address <<= 8;
+ address |= get_pair();
+ length--;
+ }
+ if (address == -1) {
+ eof = 1;
+ continue;
+ }
+ client_pc = address;
+ if (length) {
+ *(char *) 0xbd000020 = display_error_bad_7;
+ // *(char*)0xbd00000c = display_error_bad_7;
+ }
+
+ done = 1;
+ break;
+
+ default:
+ *(char *) 0xbd000020 = display_error_unknown;
+ // *(char*)0xbd00000c = display_error_unknown;
+
+ break;
+ }
+ save_csum = (~csum) & 0xff;
+ if ((csum = get_pair()) < 0) {
+ eof = 1;
+ continue;
+ }
+ if (csum != save_csum) {
+ *(char *) 0xbd000020 = display_error;
+ // *(char*)0xbd00000c = display_error;
+ } else {
+
+ if (display_counter % 50 == 0) {
+ *(char *) 0xbd000020 = display_char;
+ display_counter = 0;
+ }
+ display_counter++;
+
+ }
+ }
+ --reccount;
+ dl_entry = client_pc;
+ return dl_entry; /* Success */
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/meminit.S b/arch/mips/galileo-boards/ev64120/compressed/meminit.S
new file mode 100644
index 000000000..aa72b2cf5
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/meminit.S
@@ -0,0 +1,187 @@
+/*
+ * Define BUSWIDTH to usually be real buswidth X 2 (i.e assuming
+ * 2-way interleaving). This is so that the test pattern and
+ * inverted pattern are written to the same bank of memory, which
+ * prevents us reading back data sitting in the dram buffers and
+ * getting a false match.
+ */
+
+#ifndef BUSWIDTH
+# if #cpu(r3000) || #cpu(r4300) || #cpu(r4650)
+# define BUSWIDTH 8 /* 32 bit memory, bank interleaved */
+# elif #cpu(r4000)
+# define BUSWIDTH 16 /* 64 bit memory, bank interleaved */
+# endif
+#endif
+
+#ifndef RAM_BASE
+#define RAM_BASE KSEG1_BASE
+#endif
+
+#ifndef MEMSTART
+#define MEMSTART 0x0 /* start of physical memory */
+#endif
+
+#ifndef MEMINCR
+# define MEMINCR 0x10000 /* work up in 64Kb increments */
+#endif
+
+SLEAF(size_mem)
+ mfc0 t8,C0_STATUS
+#if #cpu(r4000)
+ /* disable cache and memory parity checking */
+ or t0,t8,SR_DE
+ mtc0 t0,C0_STATUS
+#endif
+
+ li t0,RAM_BASE+MEMSTART # start at bottom of phys mem
+ move t1,t0 # remember start address
+ li t2,0xaa55aa55 # pattern
+ not t3,t2 # ~pattern
+
+ move t7,k0
+ la t4,.fail # bus error exception catcher
+ addu k0,t4,s8 # RELOC
+
+ /* fill first 64Kb with zero (for cache init) */
+ move t4,t0
+ li t5,0x10000
+1: sw zero,0(t4)
+ sw zero,4(t4)
+ sw zero,8(t4)
+ sw zero,12(t4)
+ subu t5,16
+ addu t4,16
+ bnez t5,1b
+
+.loop:
+ addu t0,MEMINCR
+ move t4,t0
+
+ /* store pattern in bank 0, line 0 */
+ sw t2,0(t4)
+ addu t4,4
+
+#if BUSWIDTH > 4
+ /* fill remainder of line with zeros */
+ li t5,BUSWIDTH-4
+1: sw zero,0(t4)
+ subu t5,4
+ addu t4,4
+ bnez t5,1b
+#endif
+
+ /* store inverse pattern in bank 0, line 1 */
+ sw t3,0(t4)
+ addu t4,4
+
+#if BUSWIDTH > 4
+ /* fill remainder of line with zeros */
+ li t5,BUSWIDTH-4
+1: sw zero,0(t4)
+ subu t5,4
+ addu t4,4
+ bnez t5,1b
+#endif
+
+ /* defeat write buffering */
+#if #cpu(r4000)
+ sync
+#else
+ lw zero,-4(t4)
+#endif
+
+ lw t4,0(t0) # read first word of line
+ lw t5,0(t1) # read start of memory (should be zero)
+ bne t4,t2,.fail # this line wrong?
+ beq t5,zero,.loop # start of mem overwritten?
+
+.fail:
+ move k0,t7 # clear exception catcher
+
+ /* restore Status register */
+ mtc0 t8,C0_STATUS
+
+ /* return top of memory offset (normally == size) */
+ subu v0,t0,RAM_BASE
+ j ra
+END(size_mem)
+
+
+/*
+ * We must often initialise memory so that it has good parity/ecc,
+ * and this must be done before the caches are used.
+ */
+
+/*
+ clear_mem (size)
+ - clear memory from RAM_BASE+MEMSTART to RAM_BASE+MEMSTART+size
+ clear_mem_range (size, start)
+ - clear memory from start to start+size
+*/
+
+SLEAF(clear_mem)
+ li a1,RAM_BASE+MEMSTART # start at bottom of phys mem
+clear_mem_range:
+ beqz a0,9f
+ addu a0,a1 # end of memory
+
+ /* XXX should run cached, but caches may not be initialised yet */
+ .set noreorder
+#if __mips >= 3
+1: sd zero,0(a1)
+ sd zero,8(a1)
+ sd zero,16(a1)
+ sd zero,24(a1)
+ sd zero,32(a1)
+ sd zero,40(a1)
+ sd zero,48(a1)
+ addu a1,64
+ bne a1,a0,1b
+ sd zero,-8(a1) # BDSLOT
+#else
+1: sw zero,0(a1)
+ sw zero,4(a1)
+ sw zero,8(a1)
+ sw zero,12(a1)
+ sw zero,16(a1)
+ sw zero,20(a1)
+ sw zero,24(a1)
+ sw zero,28(a1)
+ sw zero,32(a1)
+ sw zero,36(a1)
+ sw zero,40(a1)
+ sw zero,44(a1)
+ sw zero,48(a1)
+ sw zero,52(a1)
+ sw zero,56(a1)
+ addu a1,64
+ bne a1,a0,1b
+ sw zero,-4(a1) # BDSLOT
+#endif
+ .set reorder
+
+9: j ra
+END(clear_mem)
+
+
+SLEAF(init_tlb)
+ /* initialise tlb */
+ mtc0 zero,C0_TLBLO0 /* tlblo0 = invalid */
+ mtc0 zero,C0_TLBLO1 /* tlblo1 = invalid */
+ mtc0 zero,C0_PGMASK
+ li t8,K1BASE /* tlbhi = impossible vpn */
+ li t9,(NTLBENTRIES-1) /* index */
+
+ .set noreorder
+ nop
+1: mtc0 t8,C0_TLBHI
+ mtc0 t9,C0_INX
+ addu t8,0x2000 /* inc vpn */
+ tlbwi
+ bnez t9,1b
+ subu t9,1 # BDSLOT
+ .set reorder
+
+ j ra
+END(init_tlb)
diff --git a/arch/mips/galileo-boards/ev64120/compressed/memory.c b/arch/mips/galileo-boards/ev64120/compressed/memory.c
new file mode 100644
index 000000000..e88985cb9
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/memory.c
@@ -0,0 +1,593 @@
+/* Memory.c - Memory mappings and remapping functions */
+
+/* Copyright - Galileo technology. */
+
+/*
+DESCRIPTION
+This file contains function which gives the user the ability to remap the
+SDRAM memory and devices windows, please pay attention to overlapping windows
+since the function do not take care of that for you.
+When remapping the SDRAM or devices memory space pay attention to the PCI
+mappings and make sure to coordinate between the two interfaces!!!
+*/
+
+/* includes */
+
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/core.h>
+#include <asm/galileo-boards/evb64120A/memory.h>
+#else
+#include "Core.h"
+#include "Memory.h"
+#endif
+
+/********************************************************************
+* getMemoryBankBaseAddress - Extract the base address of a memory bank
+* - If the memory bank size is 0 then this base address has no meaning !!!
+*
+* INPUTS: MEMORY_BANK bank - SDRAM Bank number.
+* OUTPUT: N/A
+* RETURNS: Memory bank base address.
+*********************************************************************/
+unsigned int getMemoryBankBaseAddress(MEMORY_BANK bank)
+{
+ unsigned int base, regBase;
+ GT_REG_READ((SCS_1_0_LOW_DECODE_ADDRESS + (bank / 2) * 0x10),
+ &base);
+ base = base << 21;
+ GT_REG_READ((SCS_0_LOW_DECODE_ADDRESS + bank * 8), &regBase);
+ base = base | (regBase << 20);
+ return base;
+}
+
+/********************************************************************
+* getDeviceBaseAddress - Extract the base address of a device.
+* - If the device size is 0 then this base address has no meaning!!!
+*
+* INPUT: DEVICE device - Bank number.
+* OUTPUT: N/A
+* RETURNS: Device base address.
+*********************************************************************/
+unsigned int getDeviceBaseAddress(DEVICE device)
+{
+ unsigned int base, regBase;
+ GT_REG_READ((CS_2_0_LOW_DECODE_ADDRESS + (device / 3) * 0x10),
+ &base);
+ base = base << 21;
+ GT_REG_READ((CS_0_LOW_DECODE_ADDRESS + device * 0x8), &regBase);
+ base = base | (regBase << 20);
+ return base;
+}
+
+/********************************************************************
+* getMemoryBankSize - Extract the size of a memory bank.
+*
+* INPUT: MEMORY_BANK bank - Bank number
+* OUTPUT: N/A
+* RETURNS: Memory bank size.
+*********************************************************************/
+unsigned int getMemoryBankSize(MEMORY_BANK bank)
+{
+ unsigned int size, base, value;
+ base = getMemoryBankBaseAddress(bank);
+ GT_REG_READ((SCS_0_HIGH_DECODE_ADDRESS + bank * 8), &size);
+ size = ((size + 1) << 20) - (base & 0x0fffffff);
+ GT_REG_READ((SCS_0_HIGH_DECODE_ADDRESS + bank * 8), &value);
+ if (value == 0)
+ return 0;
+ else
+ return size;
+}
+
+/********************************************************************
+* getDeviceSize - Extract the size of a device memory space
+*
+* INPUT: DEVICE device - Device number
+* OUTPUT: N/A
+* RETURNS: Size of a device memory space.
+*********************************************************************/
+unsigned int getDeviceSize(DEVICE device)
+{
+ unsigned int size, base, value;
+ base = getDeviceBaseAddress(device);
+ GT_REG_READ((CS_0_HIGH_DECODE_ADDRESS + device * 8), &size);
+ size = ((size + 1) << 20) - (base & 0x0fffffff);
+ GT_REG_READ((CS_0_HIGH_DECODE_ADDRESS + device * 8), &value);
+ if ((value + 1) == 0)
+ return 0;
+ else
+ return size;
+}
+
+/********************************************************************
+* getDeviceWidth - A device can be with: 1,2,4 or 8 Bytes data width.
+* The width is determine in registers: 'Device Parameters'
+* registers (0x45c, 0x460, 0x464, 0x468, 0x46c - for each device.
+* at bits: [21:20].
+*
+* INPUT: DEVICE device - Device number
+* OUTPUT: N/A
+* RETURNS: Device width in Bytes (1,2,4, or 8), 0 if error had occurred.
+*********************************************************************/
+unsigned int getDeviceWidth(DEVICE device)
+{
+ unsigned int width;
+ unsigned int regValue;
+
+ GT_REG_READ(DEVICE_BANK0PARAMETERS + device * 4, &regValue);
+ width = (regValue & 0x00300000) >> 20;
+ switch (width) {
+ case 0:
+ return 1;
+ case 1:
+ return 2;
+ case 2:
+ return 4;
+ case 3:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+/********************************************************************
+* mapMemoryBanks0and1 - Sets new bases and boundaries for memory banks 0 and 1
+* - Pay attention to the PCI mappings and make sure to
+* coordinate between the two interfaces!!!
+* - It is the programmer`s responsibility to make sure
+* there are no conflicts with other memory spaces!!!
+* - If a bank needs to be closed , give it a 0 length
+*
+*
+* INPUTS: unsigned int bank0Base - required bank 0 base address.
+* unsigned int bank0Length - required bank 0 size.
+* unsigned int bank1Base - required bank 1 base address.
+* unsigned int bank1Length - required bank 1 size.
+* RETURNS: true on success, false on failure or if one of the parameters is
+* erroneous.
+*********************************************************************/
+bool mapMemoryBanks0and1(unsigned int bank0Base, unsigned int bank0Length,
+ unsigned int bank1Base, unsigned int bank1Length)
+{
+ unsigned int mainBank0Top = bank0Base + bank0Length;
+ unsigned int mainBank1Top = bank1Base + bank1Length;
+ unsigned int memBank0Base, bank0Top;
+ unsigned int memBank1Base, bank1Top;
+
+ if (bank0Base <= bank1Base) {
+ if ((bank0Base + bank0Length) > bank1Base)
+ return false;
+ } else {
+ if ((bank1Base + bank1Length) > bank0Base)
+ return false;
+ }
+
+ if (bank0Length == 0)
+ mainBank0Top++;
+ if (bank1Length == 0)
+ mainBank1Top++;
+
+ memBank0Base = ((unsigned int) (bank0Base & 0x0fffffff)) >> 20;
+ bank0Top = ((unsigned int) (mainBank0Top & 0x0fffffff)) >> 20;
+ memBank1Base = ((unsigned int) (bank1Base & 0x0fffffff)) >> 20;
+ bank1Top = ((unsigned int) (mainBank1Top & 0x0fffffff)) >> 20;
+
+ if (mainBank1Top > mainBank0Top) {
+ bank0Base >>= 21;
+ mainBank0Top =
+ ((unsigned int) (mainBank1Top & 0x0fffffff)) >> 21;
+ } else {
+ bank0Base = bank1Base >> 21;
+ mainBank0Top =
+ ((unsigned int) (mainBank0Top & 0x0fffffff)) >> 21;
+ }
+ GT_REG_WRITE(SCS_1_0_LOW_DECODE_ADDRESS, bank0Base);
+ if ((bank0Length + bank1Length) != 0) {
+ GT_REG_WRITE(SCS_1_0_HIGH_DECODE_ADDRESS,
+ mainBank0Top - 1);
+ } else {
+ GT_REG_WRITE(SCS_1_0_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ if (bank1Length != 0) {
+ GT_REG_WRITE(SCS_1_HIGH_DECODE_ADDRESS, bank1Top - 1);
+ } else {
+ GT_REG_WRITE(SCS_1_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(SCS_1_LOW_DECODE_ADDRESS, memBank1Base);
+ if (bank0Length != 0) {
+ GT_REG_WRITE(SCS_0_HIGH_DECODE_ADDRESS, bank0Top - 1);
+ } else {
+ GT_REG_WRITE(SCS_0_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(SCS_0_LOW_DECODE_ADDRESS, memBank0Base);
+ return true;
+}
+
+/********************************************************************
+* mapMemoryBanks2and3 - Sets new bases and boundaries for memory banks 2 and 3
+* - Pay attention to the PCI mappings and make sure to
+* coordinate between the two interfaces!!!
+* - It`s the programmer`s responsibility to make sure there
+* are no conflicts with other memory spaces!!!
+* - If a bank needs to be closed , give it a 0 length.
+*
+*
+* INPUTS: unsigned int bank2Base - required bank 2 base address.
+* unsigned int bank2Length - required bank 2 size.
+* unsigned int bank3Base - required bank 3 base address.
+* unsigned int bank3Length - required bank 3 size.
+* RETURNS: true on success, false on failure or if one of the parameters is
+* erroneous.
+*********************************************************************/
+bool mapMemoryBanks2and3(unsigned int bank2Base, unsigned int bank2Length,
+ unsigned int bank3Base, unsigned int bank3Length)
+{
+ unsigned int mainBank2Top =
+ (unsigned int) (bank2Base + bank2Length);
+ unsigned int mainBank3Top =
+ (unsigned int) (bank3Base + bank3Length);
+ unsigned int memBank2Base, bank2Top;
+ unsigned int memBank3Base, bank3Top;
+
+ if (bank2Base <= bank3Base) {
+ if ((bank2Base + bank2Length) > bank3Base)
+ return false;
+ } else {
+ if ((bank3Base + bank3Length) > bank2Base)
+ return false;
+ }
+ if (bank2Length == 0)
+ mainBank2Top++;
+ if (bank3Length == 0)
+ mainBank3Top++;
+
+ memBank2Base = ((unsigned int) (bank2Base & 0x0fffffff)) >> 20;
+ bank2Top = ((unsigned int) (mainBank2Top & 0x0fffffff)) >> 20;
+ memBank3Base = ((unsigned int) (bank3Base & 0x0fffffff)) >> 20;
+ bank3Top = ((unsigned int) (mainBank3Top & 0x0fffffff)) >> 20;
+
+ if (mainBank3Top > mainBank2Top) {
+ bank2Base >>= 21;
+ mainBank2Top =
+ ((unsigned int) (mainBank3Top & 0x0fffffff)) >> 21;
+ } else {
+ bank2Base = bank3Base >> 21;
+ mainBank2Top =
+ ((unsigned int) (mainBank2Top & 0x0fffffff)) >> 21;
+ }
+ GT_REG_WRITE(SCS_3_2_LOW_DECODE_ADDRESS, bank2Base);
+ if ((bank2Length + bank3Length) != 0) {
+ GT_REG_WRITE(SCS_3_2_HIGH_DECODE_ADDRESS,
+ mainBank2Top - 1);
+ } else {
+ GT_REG_WRITE(SCS_3_2_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ if (bank3Length != 0) {
+ GT_REG_WRITE(SCS_3_HIGH_DECODE_ADDRESS, bank3Top - 1);
+ } else {
+ GT_REG_WRITE(SCS_3_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(SCS_3_LOW_DECODE_ADDRESS, memBank3Base);
+ if (bank2Length != 0) {
+ GT_REG_WRITE(SCS_2_HIGH_DECODE_ADDRESS, bank2Top - 1);
+ } else {
+ GT_REG_WRITE(SCS_2_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(SCS_2_LOW_DECODE_ADDRESS, memBank2Base);
+ return true;
+}
+
+/********************************************************************
+* mapDevices0_1and2MemorySpace - Sets new bases and boundaries for devices 0,1
+* and 2
+* - Pay attention to the PCI mappings and make sure to
+* coordinate between the two interfaces!!!
+* - It`s the programmer`s responsibility to make sure there
+* are no conflicts with other memory spaces!!!
+* - If a device needs to be closed , give it a 0 length
+*
+*
+* INPUTS: unsigned int device0Base - required cs_0 base address.
+* unsigned int device0Length - required cs_0 size.
+* unsigned int device1Base - required cs_1 base address.
+* unsigned int device1Length - required cs_0 size.
+* unsigned int device2Base - required cs_2 base address.
+* unsigned int device2Length - required cs_2 size.
+* RETURNS: true on success, false on failure or if one of the parameters is
+* erroneous.
+*********************************************************************/
+bool mapDevices0_1and2MemorySpace(unsigned int device0Base,
+ unsigned int device0Length,
+ unsigned int device1Base,
+ unsigned int device1Length,
+ unsigned int device2Base,
+ unsigned int device2Length)
+{
+ unsigned int deviceBank0Top =
+ (unsigned int) (device0Base + device0Length);
+ unsigned int deviceBank1Top =
+ (unsigned int) (device1Base + device1Length);
+ unsigned int deviceBank2Top =
+ (unsigned int) (device2Base + device2Length);
+ unsigned int device0BaseTemp = 0, device0TopTemp = 0;
+ unsigned int bank0Base, bank0Top;
+ unsigned int bank1Base, bank1Top;
+ unsigned int bank2Base, bank2Top;
+ bank0Base = ((unsigned int) (device0Base & 0x0fffffff)) >> 20;
+ bank0Top = ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 20;
+ bank1Base = ((unsigned int) (device1Base & 0x0fffffff)) >> 20;
+ bank1Top = ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 20;
+ bank2Base = ((unsigned int) (device2Base & 0x0fffffff)) >> 20;
+ bank2Top = ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 20;
+
+ if (device0Length == 0)
+ deviceBank0Top++;
+ if (device1Length == 0)
+ deviceBank1Top++;
+ if (device2Length == 0)
+ deviceBank2Top++;
+
+ if (device0Base <= device1Base && device0Base <= device2Base) {
+ if ((device0Base + device0Length) > device1Base || \
+ (device0Base + device0Length) > device2Base)
+ return false;
+ if (device1Base <= device2Base) {
+ if ((device1Base + device1Length) > device2Base)
+ return false;
+ } else {
+ if ((device2Base + device2Length) > device1Base)
+ return false;
+ }
+ }
+
+ if (device1Base <= device0Base && device1Base <= device2Base) {
+ if ((device1Base + device1Length) > device0Base ||
+ (device1Base + device1Length) > device2Base)
+ return false;
+ if (device0Base <= device2Base) {
+ if ((device0Base + device0Length) > device2Base)
+ return false;
+ } else {
+ if ((device2Base + device2Length) > device0Base)
+ return false;
+ }
+ }
+
+ if (device2Base <= device1Base && device2Base <= device0Base) {
+ if ((device2Base + device2Length) > device1Base ||
+ (device2Base + device2Length) > device0Base)
+ return false;
+ if (device0Base <= device1Base) {
+ if ((device0Base + device0Length) > device1Base)
+ return false;
+ } else {
+ if ((device1Base + device1Length) > device0Base)
+ return false;
+ }
+ }
+
+ if ((deviceBank2Top > deviceBank1Top) && (deviceBank1Top >
+ deviceBank0Top)) {
+ device0BaseTemp = device0Base >> 21;
+ device0TopTemp =
+ ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 21;
+ }
+ if ((deviceBank2Top > deviceBank0Top)
+ && (deviceBank0Top > deviceBank1Top)) {
+ device0BaseTemp = device1Base >> 21;
+ device0TopTemp =
+ ((unsigned int) (deviceBank2Top & 0x0fffffff)) >> 21;
+ }
+ if ((deviceBank1Top > deviceBank2Top)
+ && (deviceBank2Top > deviceBank0Top)) {
+ device0BaseTemp = device0Base >> 21;
+ device0TopTemp =
+ ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 21;
+ }
+ if ((deviceBank1Top > deviceBank0Top)
+ && (deviceBank0Top > deviceBank2Top)) {
+ device0BaseTemp = device2Base >> 21;
+ device0TopTemp =
+ ((unsigned int) (deviceBank1Top & 0x0fffffff)) >> 21;
+ }
+ if ((deviceBank0Top > deviceBank2Top)
+ && (deviceBank2Top > deviceBank1Top)) {
+ device0BaseTemp = device1Base >> 21;
+ device0TopTemp =
+ ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 21;
+ }
+ if ((deviceBank0Top > deviceBank1Top)
+ && (deviceBank1Top > deviceBank2Top)) {
+ device0BaseTemp = device2Base >> 21;
+ device0TopTemp =
+ ((unsigned int) (deviceBank0Top & 0x0fffffff)) >> 21;
+ }
+ GT_REG_WRITE(CS_2_0_LOW_DECODE_ADDRESS, device0BaseTemp);
+ if ((device0Length + device1Length + device2Length) != 0) {
+ GT_REG_WRITE(CS_2_0_HIGH_DECODE_ADDRESS,
+ device0TopTemp - 1);
+ } else {
+ GT_REG_WRITE(CS_2_0_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(CS_0_LOW_DECODE_ADDRESS, bank0Base);
+ if (device0Length != 0) {
+ GT_REG_WRITE(CS_0_HIGH_DECODE_ADDRESS, bank0Top - 1);
+ } else {
+ GT_REG_WRITE(CS_0_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(CS_1_LOW_DECODE_ADDRESS, bank1Base);
+ if (device1Length != 0) {
+ GT_REG_WRITE(CS_1_HIGH_DECODE_ADDRESS, bank1Top - 1);
+ } else {
+ GT_REG_WRITE(CS_1_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(CS_2_LOW_DECODE_ADDRESS, bank2Base);
+ if (device2Length != 0) {
+ GT_REG_WRITE(CS_2_HIGH_DECODE_ADDRESS, bank2Top - 1);
+ } else {
+ GT_REG_WRITE(CS_2_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ return true;
+}
+
+/********************************************************************
+* mapDevices3andBootMemorySpace - Sets new bases and boundaries for devices:
+* 3 and boot
+* - Pay attention to the PCI mappings and make sure to
+* coordinate between the two interfaces!!!
+* - It is the programmer`s responsibility to make sure
+* there are no conflicts with other memory spaces!!!
+* - If a device needs to be closed , give it a 0 length.
+*
+* INPUTS: base and length of device 3and boot
+* RETURNS: true on success, false on failure
+*********************************************************************/
+bool mapDevices3andBootMemorySpace(unsigned int device3Base,
+ unsigned int device3Length,
+ unsigned int bootDeviceBase,
+ unsigned int bootDeviceLength)
+{
+ unsigned int deviceBank3Top =
+ (unsigned int) (device3Base + device3Length);
+ unsigned int deviceBankBootTop =
+ (unsigned int) (bootDeviceBase + bootDeviceLength);
+ unsigned int bank3Base, bank3Top;
+ unsigned int bank4Base, bank4Top;
+ unsigned int Device1Base, Device1Top;
+
+ bank3Top = ((unsigned int) (deviceBank3Top & 0x0fffffff)) >> 20;
+ bank4Top = ((unsigned int) (deviceBankBootTop & 0x0fffffff)) >> 20;
+ bank3Base = ((unsigned int) (device3Base & 0x0fffffff)) >> 20;
+ bank4Base = ((unsigned int) (bootDeviceBase & 0x0fffffff)) >> 20;
+
+ if (device3Base <= bootDeviceBase) {
+ if (deviceBank3Top > bootDeviceBase)
+ return false;
+ } else {
+ if (deviceBankBootTop > device3Base)
+ return false;
+ }
+
+ if (deviceBankBootTop > deviceBank3Top) {
+ Device1Base = device3Base >> 21;
+ Device1Top =
+ ((unsigned int) (deviceBankBootTop & 0x0fffffff)) >>
+ 21;
+ } else {
+ Device1Base = bootDeviceBase >> 21;
+ Device1Top =
+ ((unsigned int) (deviceBank3Top & 0x0fffffff)) >> 21;
+ }
+ GT_REG_WRITE(CS_3_BOOTCS_LOW_DECODE_ADDRESS, Device1Base);
+ if ((device3Length + bootDeviceLength) != 0) {
+ GT_REG_WRITE(CS_3_BOOTCS_HIGH_DECODE_ADDRESS,
+ Device1Top - 1);
+ } else {
+ GT_REG_WRITE(CS_3_BOOTCS_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(CS_3_LOW_DECODE_ADDRESS, bank3Base);
+ if (device3Length != 0) {
+ GT_REG_WRITE(CS_3_HIGH_DECODE_ADDRESS, bank3Top - 1);
+ } else {
+ GT_REG_WRITE(CS_3_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ GT_REG_WRITE(BOOTCS_LOW_DECODE_ADDRESS, bank4Base);
+ if (bootDeviceLength != 0) {
+ GT_REG_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, bank4Top - 1);
+ } else {
+ GT_REG_WRITE(BOOTCS_HIGH_DECODE_ADDRESS, 0x0);
+ }
+ return true;
+}
+
+/********************************************************************
+* modifyDeviceParameters - This function can be used to modify a device`s
+* parameters.
+* - Be advised to check the spec before modifying them.
+* Inputs:
+* Returns: false if one of the parameters is erroneous,true otherwise.
+*********************************************************************/
+bool modifyDeviceParameters(DEVICE device, unsigned int turnOff,
+ unsigned int accToFirst,
+ unsigned int accToNext, unsigned int aleToWr,
+ unsigned int wrActive, unsigned int wrHigh,
+ unsigned int width, bool paritySupport)
+{
+ unsigned int data, oldValue;
+
+ if ((turnOff > 0x7 && turnOff != DONT_MODIFY)
+ || (accToFirst > 0xf && accToFirst != DONT_MODIFY)
+ || (accToNext > 0xf && accToNext != DONT_MODIFY)
+ || (aleToWr > 0x7 && aleToWr != DONT_MODIFY)
+ || (wrActive > 0x7 && wrActive != DONT_MODIFY)
+ || (wrHigh > 0x7 && wrHigh != DONT_MODIFY)) {
+ return false;
+ }
+
+ GT_REG_READ((DEVICE_BANK0PARAMETERS + device * 4), &oldValue);
+ if (turnOff == DONT_MODIFY)
+ turnOff = oldValue & 0x00000007;
+ else
+ turnOff = turnOff;
+
+ if (accToFirst == DONT_MODIFY)
+ accToFirst = oldValue & 0x00000078;
+ else
+ accToFirst = accToFirst << 3;
+
+ if (accToNext == DONT_MODIFY)
+ accToNext = oldValue & 0x00000780;
+ else
+ accToNext = accToNext << 7;
+
+ if (aleToWr == DONT_MODIFY)
+ aleToWr = oldValue & 0x00003800;
+ else
+ aleToWr = aleToWr << 11;
+
+ if (wrActive == DONT_MODIFY)
+ wrActive = oldValue & 0x0001c000;
+ else
+ wrActive = wrActive << 14;
+
+ if (wrHigh == DONT_MODIFY)
+ wrHigh = oldValue & 0x000e0000;
+ else
+ wrHigh = wrHigh << 17;
+
+ data =
+ turnOff | accToFirst | accToNext | aleToWr | wrActive | wrHigh;
+ switch (width) {
+ case _8BIT:
+ break;
+ case _16BIT:
+ data = data | _16BIT;
+ break;
+ case _32BIT:
+ data = data | _32BIT;
+ break;
+ case _64BIT:
+ data = data | _64BIT;
+ break;
+ default:
+ return false;
+ }
+ if (paritySupport == true)
+ data = data | PARITY_SUPPORT;
+ GT_REG_WRITE(DEVICE_BANK0PARAMETERS + device * 4, data);
+ return true;
+}
+
+/********************************************************************
+* remapAddress - This fubction used for address remapping
+* Inputs: - regOffset: remap register
+* remapHeader : remapped address
+* Returns: false if one of the parameters is erroneous,true otherwise.
+*********************************************************************/
+bool remapAddress(unsigned int remapReg, unsigned int remapValue)
+{
+ unsigned int valueForReg;
+ valueForReg = (remapValue & 0xffe00000) >> 21;
+ GT_REG_WRITE(remapReg, valueForReg);
+ return true;
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/misc.c b/arch/mips/galileo-boards/ev64120/compressed/misc.c
new file mode 100644
index 000000000..b8f20a000
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/misc.c
@@ -0,0 +1,313 @@
+/*
+ * arch/mips/galileo/misc.c
+ *
+ * This is a collection of several routines from gzip-1.0.3
+ * adapted for Linux.
+ *
+ * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
+ * puts by Nick Holloway 1993, better puts by Martin Mares 1995
+ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+ *
+ * Modified by RidgeRun Inc.
+ */
+
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+/*
+ * gzip declarations
+ */
+
+#define OF(args) args
+#define STATIC static
+
+#define channel 1
+
+#undef memset
+#undef memcpy
+#define memzero(s, n) memset ((s), 0, (n))
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+#define WSIZE 0x8000 /* Window size must be at least 32k, */
+ /* and a power of two */
+
+static uch *inbuf; /* input buffer */
+static uch window[WSIZE]; /* Sliding window buffer */
+
+static unsigned insize = 0; /* valid bytes in inbuf */
+static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
+static unsigned outcnt = 0; /* bytes in output buffer */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
+#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
+#define RESERVED 0xC0 /* bit 6,7: reserved */
+
+void variable_init();
+static void puts(const char *);
+
+void int2hex(int i)
+{
+ int tth, th, h, t, d;
+
+ if (i > 99999) {
+ serial_putc(channel, "Error - int2hex outofbounds");
+ return;
+ }
+
+ tth = (i) / 10000;
+ th = (i - (tth * 10000)) / 1000;
+ h = (i - ((tth * 10000) + (th * 1000))) / 100;
+ t = (i - ((tth * 10000) + (th * 1000) + (h * 100))) / 10;
+ d = (i - ((tth * 10000) + (th * 1000) + (h * 100) + (t * 10)));
+ serial_putc(channel, tth + '0');
+ serial_putc(channel, th + '0');
+ serial_putc(channel, h + '0');
+ serial_putc(channel, t + '0');
+ serial_putc(channel, d + '0');
+}
+
+int checksum;
+int byte_count;
+static unsigned char *input_data;
+
+static int printCnt = 0;
+
+int get_byte()
+{
+ unsigned char c = (inptr < insize ? inbuf[inptr++] : fill_inbuf());
+ byte_count++;
+ checksum += c;
+
+ // if (printCnt++ < 150)
+ // {
+ // puts("\n");
+ // puts("byte count = ");
+ // int2hex(byte_count & 0xff);
+ // puts(" byte val = ");
+ // int2hex(c);
+ // puts(" checksum = ");
+ // int2hex(checksum & 0xff);
+ // puts("\n");
+ // }
+ return c;
+}
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# define Assert(cond,msg) {if(!(cond)) error(msg);}
+# define Trace(x) fprintf x
+# define Tracev(x) {if (verbose) fprintf x ;}
+# define Tracevv(x) {if (verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+static int fill_inbuf(void);
+static void flush_window(void);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+/*
+ * This is set up by the setup-routine at boot-time
+ */
+
+
+#define STACK_SIZE (4096)
+long user_stack[STACK_SIZE];
+long *stack_start = &user_stack[STACK_SIZE];
+
+extern int linux_compressed_start;
+extern int linux_compressed_size;
+extern int malloc_start;
+
+static int input_len;
+
+static long bytes_out = 0;
+extern int kernel_location_start;
+static uch *output_data;
+static unsigned long output_ptr = 0;
+
+
+static void *malloc(int size);
+static void free(void *where);
+static void error(char *m);
+static void gzip_mark(void **);
+static void gzip_release(void **);
+
+static unsigned long free_mem_ptr;
+static unsigned long free_mem_end_ptr;
+
+#include "../../../../../lib/inflate.c"
+
+static void *malloc(int size)
+{
+ void *p;
+
+ if (size < 0)
+ error("Malloc error\n");
+ // if (free_mem_ptr <= 0) error("Memory error\n");
+
+ free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
+
+ p = (void *) free_mem_ptr;
+ free_mem_ptr += size;
+
+ if (free_mem_ptr >= free_mem_end_ptr)
+ error("\nOut of memory\n");
+
+ return p;
+}
+
+static void free(void *where)
+{ /* Don't care */
+}
+
+static void gzip_mark(void **ptr)
+{
+ *ptr = (void *) free_mem_ptr;
+}
+
+static void gzip_release(void **ptr)
+{
+ free_mem_ptr = (long) *ptr;
+}
+
+static void puts(const char *s)
+{
+ while (*s) {
+ if (*s == 10)
+ serial_putc(channel, 13);
+ serial_putc(channel, *s++);
+ }
+}
+
+void *memset(void *s, int c, size_t n)
+{
+ int i;
+ char *ss = (char *) s;
+
+ for (i = 0; i < n; i++)
+ ss[i] = c;
+ return s;
+}
+
+void *memcpy(void *__dest, __const void *__src, size_t __n)
+{
+ int i;
+ char *d = (char *) __dest, *s = (char *) __src;
+
+ for (i = 0; i < __n; i++)
+ d[i] = s[i];
+ return __dest;
+}
+
+/* ===========================================================================
+ * Fill the input buffer. This is called only when the buffer is empty
+ * and at least one byte is really needed.
+ */
+static int fill_inbuf(void)
+{
+ if (insize != 0) {
+ error("ran out of input data\n");
+ }
+
+ inbuf = input_data;
+ insize = input_len;
+ inptr = 1;
+ return inbuf[0];
+}
+
+/* ===========================================================================
+ * Write the output window window[0..outcnt-1] and update crc and bytes_out.
+ * (Used for the decompressed data only.)
+ */
+static void flush_window(void)
+{
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, *out, ch;
+
+ in = window;
+ out = &output_data[output_ptr];
+ for (n = 0; n < outcnt; n++) {
+ ch = *out++ = *in++;
+ c = crc_32_tab[((int) c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg) outcnt;
+ output_ptr += (ulg) outcnt;
+ outcnt = 0;
+}
+
+check_mem()
+{
+ int i;
+
+ puts("\ncplens = ");
+ for (i = 0; i < 10; i++) {
+ int2hex(cplens[i]);
+ puts(" ");
+ }
+ puts("\ncplext = ");
+ for (i = 0; i < 10; i++) {
+ int2hex(cplext[i]);
+ puts(" ");
+ }
+ puts("\nborder = ");
+ for (i = 0; i < 10; i++) {
+ int2hex(border[i]);
+ puts(" ");
+ }
+ puts("\n");
+}
+
+static void error(char *x)
+{
+ check_mem();
+ puts("\n\n");
+ puts(x);
+ puts("byte_count = ");
+ int2hex(byte_count);
+ puts("\n");
+ puts("\n\n -- System halted");
+ while (1); /* Halt */
+}
+
+void variable_init()
+{
+ byte_count = 0;
+ checksum = 0;
+ input_data = (unsigned char *) &linux_compressed_start;
+ input_len = linux_compressed_size;
+ output_data = &kernel_location_start;
+ free_mem_ptr = (long) &malloc_start;
+ free_mem_end_ptr = (long) ((char *) &malloc_start + 0x400000);
+}
+
+int decompress_kernel()
+{
+ //check_mem();
+
+ variable_init();
+
+ makecrc();
+ puts("Uncompressing Linux... \n");
+ gunzip(); // ...see inflate.c
+ puts("Ok, booting the kernel.\n");
+ return 0;
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/ns16550.h b/arch/mips/galileo-boards/ev64120/compressed/ns16550.h
new file mode 100644
index 000000000..c10d8f6e6
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/ns16550.h
@@ -0,0 +1,126 @@
+/* NS16550 UART registers */
+
+#ifndef NS16550H
+#define NS16550H
+
+#define UART_BASE 0xbd000000
+#define NS16550_CHANA PHYS_TO_K1(UART_BASE + 0x20)
+#define NS16550_CHANB PHYS_TO_K1(UART_BASE)
+
+#ifndef NS16550_HZ
+#define NS16550_HZ 3686400
+#endif
+
+#ifdef __ASSEMBLER__
+
+#ifndef NSREG
+#define NSREG(x) ((x)*4)
+#endif
+
+#define DATA NSREG(0) /* data register (R/W) */
+#define IER NSREG(1) /* interrupt enable (W) */
+#define IIR NSREG(2) /* interrupt identification (R) */
+#define FIFO IIR /* 16550 fifo control (W) */
+#define CFCR NSREG(3) /* line control register (R/W) */
+#define MCR NSREG(4) /* modem control register (R/W) */
+#define LSR NSREG(5) /* line status register (R/W) */
+#define MSR NSREG(6) /* modem status register (R/W) */
+#define SCR NSREG(7) /* scratch register (R/W) */
+
+#else
+
+#ifndef nsreg
+#if #endian(little)
+#define nsreg(x) unsigned :24; unsigned char x;
+#else
+/*#define nsreg(x) unsigned char x; unsigned :24;*/
+#define nsreg(x) unsigned int x:8;unsigned int :24;
+#endif
+#endif
+
+typedef struct {
+ nsreg(data); /* data register (R/W) */
+ nsreg(ier); /* interrupt enable (W) */
+ nsreg(iir); /* interrupt identification (R) */
+#define fifo iir /* 16550 fifo control (W) */
+ nsreg(cfcr); /* line control register (R/W) */
+ nsreg(mcr); /* modem control register (R/W) */
+ nsreg(lsr); /* line status register (R/W) */
+ nsreg(msr); /* modem status register (R/W) */
+ nsreg(scr); /* scratch register (R/W) */
+} ns16550dev;
+#endif
+
+
+/* 16 bit baud rate divisor (lower byte in dca_data, upper in dca_ier) */
+#define BRTC(x) (NS16550_HZ / (16*(x)))
+
+/* interrupt enable register */
+#define IER_ERXRDY 0x1 /* int on rx ready */
+#define IER_ETXRDY 0x2 /* int on tx ready */
+#define IER_ERLS 0x4 /* int on line status change */
+#define IER_EMSC 0x8 /* int on modem status change */
+
+/* interrupt identification register */
+#define IIR_IMASK 0xf /* mask */
+#define IIR_RXTOUT 0xc /* receive timeout */
+#define IIR_RLS 0x6 /* receive line status */
+#define IIR_RXRDY 0x4 /* receive ready */
+#define IIR_TXRDY 0x2 /* transmit ready */
+#define IIR_NOPEND 0x1 /* nothing */
+#define IIR_MLSC 0x0 /* modem status */
+#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */
+
+/* fifo control register */
+#define FIFO_ENABLE 0x01 /* enable fifo */
+#define FIFO_RCV_RST 0x02 /* reset receive fifo */
+#define FIFO_XMT_RST 0x04 /* reset transmit fifo */
+#define FIFO_DMA_MODE 0x08 /* enable dma mode */
+#define FIFO_TRIGGER_1 0x00 /* trigger at 1 char */
+#define FIFO_TRIGGER_4 0x40 /* trigger at 4 chars */
+#define FIFO_TRIGGER_8 0x80 /* trigger at 8 chars */
+#define FIFO_TRIGGER_14 0xc0 /* trigger at 14 chars */
+
+/* character format control register */
+#define CFCR_DLAB 0x80 /* divisor latch */
+#define CFCR_SBREAK 0x40 /* send break */
+#define CFCR_PZERO 0x30 /* zero parity */
+#define CFCR_PONE 0x20 /* one parity */
+#define CFCR_PEVEN 0x10 /* even parity */
+#define CFCR_PODD 0x00 /* odd parity */
+#define CFCR_PENAB 0x08 /* parity enable */
+#define CFCR_STOPB 0x04 /* 2 stop bits */
+#define CFCR_8BITS 0x03 /* 8 data bits */
+#define CFCR_7BITS 0x02 /* 7 data bits */
+#define CFCR_6BITS 0x01 /* 6 data bits */
+#define CFCR_5BITS 0x00 /* 5 data bits */
+
+/* modem control register */
+#define MCR_LOOPBACK 0x10 /* loopback */
+#define MCR_IENABLE 0x08 /* output 2 = int enable */
+#define MCR_DRS 0x04 /* output 1 = xxx */
+#define MCR_RTS 0x02 /* enable RTS */
+#define MCR_DTR 0x01 /* enable DTR */
+
+/* line status register */
+#define LSR_RCV_FIFO 0x80 /* error in receive fifo */
+#define LSR_TSRE 0x40 /* transmitter empty */
+#define LSR_TXRDY 0x20 /* transmitter ready */
+#define LSR_BI 0x10 /* break detected */
+#define LSR_FE 0x08 /* framing error */
+#define LSR_PE 0x04 /* parity error */
+#define LSR_OE 0x02 /* overrun error */
+#define LSR_RXRDY 0x01 /* receiver ready */
+#define LSR_RCV_MASK 0x1f
+
+/* modem status register */
+#define MSR_DCD 0x80 /* DCD active */
+#define MSR_RI 0x40 /* RI active */
+#define MSR_DSR 0x20 /* DSR active */
+#define MSR_CTS 0x10 /* CTS active */
+#define MSR_DDCD 0x08 /* DCD changed */
+#define MSR_TERI 0x04 /* RI changed */
+#define MSR_DDSR 0x02 /* DSR changed */
+#define MSR_DCTS 0x01 /* CTS changed */
+
+#endif
diff --git a/arch/mips/galileo-boards/ev64120/compressed/osdep.h b/arch/mips/galileo-boards/ev64120/compressed/osdep.h
new file mode 100644
index 000000000..933c8c1c7
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/osdep.h
@@ -0,0 +1,36 @@
+#ifndef __OSDEP_H__
+#define __OSDEP_H__
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2, or (at
+ * your option) any later version.
+ */
+
+#if defined(__linux__) || defined(__FreeBSD__) || defined (__MIPSEB__)
+#define ETHERBOOT32
+#define ntohl(x) (x)
+#define htonl(x) (x)
+#define ntohs(x) (x)
+#define htons(x) (x)
+
+#endif
+
+
+
+
+/* ANSI prototyping macro */
+#ifdef __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+
+#endif
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/arch/mips/galileo-boards/ev64120/compressed/pci.c b/arch/mips/galileo-boards/ev64120/compressed/pci.c
new file mode 100644
index 000000000..9d8add1eb
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/pci.c
@@ -0,0 +1,1336 @@
+/* PCI.c - PCI functions */
+
+/* Copyright - Galileo technology. */
+
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/core.h>
+#include <asm/galileo-boards/evb64120A/pci.h>
+#ifndef PROM
+#include <linux/kernel.h>
+#endif
+
+#undef PCI_DEBUG
+
+#ifdef PCI_DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#else
+#include "core.h"
+#include "pci.h"
+#include <string.h>
+#endif
+
+/********************************************************************
+* pci0ScanDevices - This function scan PCI0 bus, if found any device on
+* this bus it interrogate the Device for the information
+* it can discover.
+* The fields with all information are the following:
+* char type[20];
+* unsigned int deviceNum;
+* unsigned int venID;
+* unsigned int deviceID;
+* unsigned int bar0Base;
+* unsigned int bar0Size;
+* unsigned int bar1Base;
+* unsigned int bar1Size;
+* unsigned int bar2Base;
+* unsigned int bar2Size;
+* unsigned int bar3Base;
+* unsigned int bar3Size;
+* unsigned int bar4Base;
+* unsigned int bar4Size;
+* unsigned int bar5Base;
+* unsigned int bar5Size;
+*
+* Inputs: PCI0_DEVICE* pci0Detect - Pointer to an array of STRUCT PCI0_DEVICE.
+* unsigned int numberOfElment - The PCI0_DEVICE Array length.
+* Output: None.
+*********************************************************************/
+
+void pci0ScanDevices(PCI_DEVICE * pci0Detect, unsigned int numberOfElment)
+{
+ PCI_DEVICE *pci0ArrayPointer = pci0Detect;
+ unsigned int id; /* PCI Configuration register 0x0. */
+ unsigned int device; /* device`s Counter. */
+ unsigned int classCode; /* PCI Configuration register 0x8 */
+ unsigned int arrayCounter = 0;
+ unsigned int memBaseAddress;
+ unsigned int memSize;
+ unsigned int c18RegValue;
+
+ PCI0_MASTER_ENABLE(SELF);
+ /* According to PCI REV 2.1 MAX agents on the bus are -21- */
+ for (device = 6; device < 8; device++) {
+ id = pci0ReadConfigReg(PCI_0DEVICE_AND_VENDOR_ID, device);
+ GT_REG_READ(INTERRUPT_CAUSE_REGISTER, &c18RegValue);
+ /* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */
+ GT_REG_WRITE(INTERRUPT_CAUSE_REGISTER,
+ c18RegValue & 0xfffbffff);
+ if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) {
+ classCode =
+ pci0ReadConfigReg
+ (PCI_0CLASS_CODE_AND_REVISION_ID, device);
+ pci0ArrayPointer->deviceNum = device;
+ pci0ArrayPointer->venID = (id & 0xffff);
+ pci0ArrayPointer->deviceID =
+ ((id & 0xffff0000) >> 16);
+ DBG("\nrr: venID %x devID %x\n",
+ pci0ArrayPointer->venID,
+ pci0ArrayPointer->deviceID);
+ DBG("rr: device found %x\n",
+ pci0ArrayPointer->deviceNum);
+ /* BAR0 parameters */
+ memBaseAddress = pci0ReadConfigReg(BAR0, device);
+ pci0ArrayPointer->bar0Type = memBaseAddress & 1;
+ pci0ArrayPointer->bar0Base =
+ memBaseAddress & 0xfffff000;
+ pci0WriteConfigReg(BAR0, device, 0xffffffff);
+ memSize = pci0ReadConfigReg(BAR0, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci0ArrayPointer->bar0Size = 0;
+ } else {
+ if (pci0ArrayPointer->bar0Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci0ArrayPointer->bar0Size = memSize;
+ }
+ DBG("rr: device BAR0 size %x\n", memSize);
+ DBG("rr: device BAR0 address %x\n",
+ memBaseAddress);
+ pci0WriteConfigReg(BAR0, device, memBaseAddress);
+ /* BAR1 parameters */
+ memBaseAddress = pci0ReadConfigReg(BAR1, device);
+ pci0ArrayPointer->bar1Type = memBaseAddress & 1;
+ pci0ArrayPointer->bar1Base =
+ memBaseAddress & 0xfffff000;
+ pci0WriteConfigReg(BAR1, device, 0xffffffff);
+ memSize = pci0ReadConfigReg(BAR1, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci0ArrayPointer->bar1Size = 0;
+ } else {
+ if (pci0ArrayPointer->bar1Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci0ArrayPointer->bar1Size = memSize;
+ }
+ DBG("rr: device BAR1 size %x\n", memSize);
+ DBG("rr: device BAR1 address %x\n",
+ memBaseAddress);
+ pci0WriteConfigReg(BAR1, device, memBaseAddress);
+ /* BAR2 parameters */
+ memBaseAddress = pci0ReadConfigReg(BAR2, device);
+ pci0ArrayPointer->bar2Type = memBaseAddress & 1;
+ pci0ArrayPointer->bar2Base =
+ memBaseAddress & 0xfffff000;
+ pci0WriteConfigReg(BAR2, device, 0xffffffff);
+ memSize = pci0ReadConfigReg(BAR2, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci0ArrayPointer->bar2Size = 0;
+ } else {
+ if (pci0ArrayPointer->bar2Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci0ArrayPointer->bar2Size = memSize;
+ }
+ DBG("rr: device BAR2 size %x\n", memSize);
+ DBG("rr: device BAR2 address %x\n",
+ memBaseAddress);
+ pci0WriteConfigReg(BAR2, device, memBaseAddress);
+ /* BAR3 parameters */
+ memBaseAddress = pci0ReadConfigReg(BAR3, device);
+ pci0ArrayPointer->bar3Type = memBaseAddress & 1;
+ pci0ArrayPointer->bar3Base =
+ memBaseAddress & 0xfffff000;
+ pci0WriteConfigReg(BAR3, device, 0xffffffff);
+ memSize = pci0ReadConfigReg(BAR3, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci0ArrayPointer->bar3Size = 0;
+ } else {
+ if (pci0ArrayPointer->bar3Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci0ArrayPointer->bar3Size = memSize;
+ }
+ DBG("rr: device BAR3 size %x\n", memSize);
+ DBG("rr: device BAR3 address %x\n",
+ memBaseAddress);
+ pci0WriteConfigReg(BAR3, device, memBaseAddress);
+ /* BAR4 parameters */
+ memBaseAddress = pci0ReadConfigReg(BAR4, device);
+ pci0ArrayPointer->bar4Type = memBaseAddress & 1;
+ pci0ArrayPointer->bar4Base =
+ memBaseAddress & 0xfffff000;
+ pci0WriteConfigReg(BAR4, device, 0xffffffff);
+ memSize = pci0ReadConfigReg(BAR4, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci0ArrayPointer->bar4Size = 0;
+ } else {
+ if (pci0ArrayPointer->bar4Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci0ArrayPointer->bar4Size = memSize;
+ }
+ DBG("rr: device BAR4 size %x\n", memSize);
+ DBG("rr: device BAR4 address %x\n",
+ memBaseAddress);
+ pci0WriteConfigReg(BAR4, device, memBaseAddress);
+ /* BAR5 parameters */
+ memBaseAddress = pci0ReadConfigReg(BAR5, device);
+ pci0ArrayPointer->bar5Type = memBaseAddress & 1;
+ pci0ArrayPointer->bar5Base =
+ memBaseAddress & 0xfffff000;
+ pci0WriteConfigReg(BAR5, device, 0xffffffff);
+ memSize = pci0ReadConfigReg(BAR5, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci0ArrayPointer->bar5Size = 0;
+ } else {
+ if (pci0ArrayPointer->bar5Type == 1) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci0ArrayPointer->bar5Size = memSize;
+ }
+ DBG("rr: device BAR5 size %x\n", memSize);
+ DBG("rr: device BAR5 address %x\n",
+ memBaseAddress);
+ pci0WriteConfigReg(BAR5, device, memBaseAddress);
+ /* End of BARs Detection. */
+
+ classCode = ((classCode & 0xff000000) >> 24);
+ switch (classCode) {
+ case 0x0:
+ strcpy(pci0ArrayPointer->type,
+ "Old generation device");
+ break;
+ case 0x1:
+ strcpy(pci0ArrayPointer->type,
+ "Mass storage controller");
+ break;
+ case 0x2:
+ strcpy(pci0ArrayPointer->type,
+ "Network controller");
+ break;
+ case 0x3:
+ strcpy(pci0ArrayPointer->type,
+ "Display controller");
+ break;
+ case 0x4:
+ strcpy(pci0ArrayPointer->type,
+ "Multimedia device");
+ break;
+ case 0x5:
+ strcpy(pci0ArrayPointer->type,
+ "Memory controller");
+ break;
+ case 0x6:
+ strcpy(pci0ArrayPointer->type,
+ "Bridge Device");
+ break;
+ case 0x7:
+ strcpy(pci0ArrayPointer->type,
+ "Simple Communication controllers");
+ break;
+ case 0x8:
+ strcpy(pci0ArrayPointer->type,
+ "Base system peripherals");
+ break;
+ case 0x9:
+ strcpy(pci0ArrayPointer->type,
+ "Input Devices");
+ break;
+ case 0xa:
+ strcpy(pci0ArrayPointer->type,
+ "Docking stations");
+ break;
+ case 0xb:
+ strcpy(pci0ArrayPointer->type,
+ "Processors");
+ break;
+ case 0xc:
+ strcpy(pci0ArrayPointer->type,
+ "Serial bus controllers");
+ break;
+ case 0xd:
+ strcpy(pci0ArrayPointer->type,
+ "Wireless controllers");
+ break;
+ case 0xe:
+ strcpy(pci0ArrayPointer->type,
+ "Intelligent I/O controllers");
+ break;
+ case 0xf:
+ strcpy(pci0ArrayPointer->type,
+ "Satellite communication controllers");
+ break;
+ case 0x10:
+ strcpy(pci0ArrayPointer->type,
+ "Encryption/Decryption controllers");
+ break;
+ case 0x11:
+ strcpy(pci0ArrayPointer->type,
+ "Data acquisition and signal processing controllers");
+ break;
+ default:
+ break;
+
+ }
+ arrayCounter++; /* point to the next element in the Array. */
+ if (arrayCounter == numberOfElment)
+ return; /* When the Array is fully used, return. */
+ /* Else, points to next free Element. */
+ pci0ArrayPointer = &pci0Detect[arrayCounter];
+ }
+ }
+ pci0ArrayPointer->deviceNum = 0; /* 0 => End of List */
+}
+
+
+/********************************************************************
+* pci1ScanDevices - This function scan PCI1 bus, if found any device on
+* this bus it interrogate the Device for the information
+* it can discover.
+* The fields with all information are the following:
+* char type[20];
+* unsigned int deviceNum;
+* unsigned int venID;
+* unsigned int deviceID;
+* unsigned int bar0Base;
+* unsigned int bar0Size;
+* unsigned int bar1Base;
+* unsigned int bar1Size;
+* unsigned int bar2Base;
+* unsigned int bar2Size;
+* unsigned int bar3Base;
+* unsigned int bar3Size;
+* unsigned int bar4Base;
+* unsigned int bar4Size;
+* unsigned int bar5Base;
+* unsigned int bar5Size;
+*
+* Inputs: Pointer to an array of STRUCT PCI1_DEVICE.
+* Output: None.
+*********************************************************************/
+
+void pci1ScanDevices(PCI_DEVICE * pci1Detect, unsigned int numberOfElment)
+{
+ PCI_DEVICE *pci1ArrayPointer = pci1Detect;
+ unsigned int id; /* PCI Configuration register 0x0. */
+ unsigned int device; /* device`s Counter. */
+ unsigned int classCode; /* PCI Configuration register 0x8 */
+ unsigned int arrayCounter = 0;
+ unsigned int memBaseAddress;
+ unsigned int memSize;
+ unsigned int c98RegValue;
+
+ PCI1_MASTER_ENABLE(SELF);
+ /* According to PCI REV 2.1 MAX agents on the bus are -21- */
+ for (device = 1; device < 22; device++) {
+ id = pci1ReadConfigReg(PCI_0DEVICE_AND_VENDOR_ID, device);
+ GT_REG_READ(HIGH_INTERRUPT_CAUSE_REGISTER, &c98RegValue);
+ /* Clearing bit 18 of in the High Cause Register 0xc98 */
+ GT_REG_WRITE(HIGH_INTERRUPT_CAUSE_REGISTER,
+ c98RegValue & 0xfffbffff);
+ if ((id != 0xffffffff) && !(c98RegValue & 0x40000)) {
+ classCode =
+ pci1ReadConfigReg
+ (PCI_0CLASS_CODE_AND_REVISION_ID, device);
+ pci1ArrayPointer->deviceNum = device;
+ pci1ArrayPointer->venID = (id & 0xffff);
+ pci1ArrayPointer->deviceID =
+ ((id & 0xffff0000) >> 16);
+
+ /* BAR0 parameters */
+ memBaseAddress = pci1ReadConfigReg(BAR0, device);
+ pci1ArrayPointer->bar0Type = memBaseAddress & 1;
+ pci1ArrayPointer->bar0Base =
+ memBaseAddress & 0xfffff000;
+ pci1WriteConfigReg(BAR0, device, 0xffffffff);
+ memSize = pci1ReadConfigReg(BAR0, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci1ArrayPointer->bar0Size = 0;
+ } else {
+ if (pci1ArrayPointer->bar0Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci1ArrayPointer->bar0Size = memSize;
+ }
+ pci1WriteConfigReg(BAR0, device, memBaseAddress);
+ /* BAR1 parameters */
+ memBaseAddress = pci1ReadConfigReg(BAR1, device);
+ pci1ArrayPointer->bar1Type = memBaseAddress & 1;
+ pci1ArrayPointer->bar1Base =
+ memBaseAddress & 0xfffff000;
+ pci1WriteConfigReg(BAR1, device, 0xffffffff);
+ memSize = pci1ReadConfigReg(BAR1, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci1ArrayPointer->bar1Size = 0;
+ } else {
+ if (pci1ArrayPointer->bar1Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci1ArrayPointer->bar1Size = memSize;
+ }
+ pci1WriteConfigReg(BAR1, device, memBaseAddress);
+ /* BAR2 parameters */
+ memBaseAddress = pci1ReadConfigReg(BAR2, device);
+ pci1ArrayPointer->bar2Type = memBaseAddress & 1;
+ pci1ArrayPointer->bar2Base =
+ memBaseAddress & 0xfffff000;
+ pci1WriteConfigReg(BAR2, device, 0xffffffff);
+ memSize = pci1ReadConfigReg(BAR2, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci1ArrayPointer->bar2Size = 0;
+ } else {
+ if (pci1ArrayPointer->bar2Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci1ArrayPointer->bar2Size = memSize;
+ }
+ pci1WriteConfigReg(BAR2, device, memBaseAddress);
+ /* BAR3 parameters */
+ memBaseAddress = pci1ReadConfigReg(BAR3, device);
+ pci1ArrayPointer->bar3Type = memBaseAddress & 1;
+ pci1ArrayPointer->bar3Base =
+ memBaseAddress & 0xfffff000;
+ pci1WriteConfigReg(BAR3, device, 0xffffffff);
+ memSize = pci1ReadConfigReg(BAR3, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci1ArrayPointer->bar3Size = 0;
+ } else {
+ if (pci1ArrayPointer->bar3Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci1ArrayPointer->bar3Size = memSize;
+ }
+ pci1WriteConfigReg(BAR3, device, memBaseAddress);
+ /* BAR4 parameters */
+ memBaseAddress = pci1ReadConfigReg(BAR4, device);
+ pci1ArrayPointer->bar4Type = memBaseAddress & 1;
+ pci1ArrayPointer->bar4Base =
+ memBaseAddress & 0xfffff000;
+ pci1WriteConfigReg(BAR4, device, 0xffffffff);
+ memSize = pci1ReadConfigReg(BAR4, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci1ArrayPointer->bar4Size = 0;
+ } else {
+ if (pci1ArrayPointer->bar4Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci1ArrayPointer->bar4Size = memSize;
+ }
+ pci1WriteConfigReg(BAR4, device, memBaseAddress);
+ /* BAR5 parameters */
+ memBaseAddress = pci1ReadConfigReg(BAR5, device);
+ pci1ArrayPointer->bar5Type = memBaseAddress & 1;
+ pci1ArrayPointer->bar5Base =
+ memBaseAddress & 0xfffff000;
+ pci1WriteConfigReg(BAR5, device, 0xffffffff);
+ memSize = pci1ReadConfigReg(BAR5, device);
+ if (memSize == 0) { /* case of an empty BAR */
+ pci1ArrayPointer->bar5Size = 0;
+ } else {
+ if (pci1ArrayPointer->bar5Type == 0) /* memory space */
+ memSize =
+ ~(memSize & 0xfffffff0) + 1;
+ else /* IO space */
+ memSize =
+ ~(memSize & 0xfffffffc) + 1;
+ pci1ArrayPointer->bar5Size = memSize;
+ }
+ pci1WriteConfigReg(BAR5, device, memBaseAddress);
+ /* End of BARs Detection. */
+
+ classCode = ((classCode & 0xff000000) >> 24);
+ switch (classCode) {
+ case 0x0:
+ strcpy(pci1ArrayPointer->type,
+ "Old generation device");
+ break;
+ case 0x1:
+ strcpy(pci1ArrayPointer->type,
+ "Mass storage controller");
+ break;
+ case 0x2:
+ strcpy(pci1ArrayPointer->type,
+ "Network controller");
+ break;
+ case 0x3:
+ strcpy(pci1ArrayPointer->type,
+ "Display controller");
+ break;
+ case 0x4:
+ strcpy(pci1ArrayPointer->type,
+ "Multimedia device");
+ break;
+ case 0x5:
+ strcpy(pci1ArrayPointer->type,
+ "Memory controller");
+ break;
+ case 0x6:
+ strcpy(pci1ArrayPointer->type,
+ "Bridge Device");
+ break;
+ case 0x7:
+ strcpy(pci1ArrayPointer->type,
+ "Simple Communication controllers");
+ break;
+ case 0x8:
+ strcpy(pci1ArrayPointer->type,
+ "Base system peripherals");
+ break;
+ case 0x9:
+ strcpy(pci1ArrayPointer->type,
+ "Input Devices");
+ break;
+ case 0xa:
+ strcpy(pci1ArrayPointer->type,
+ "Docking stations");
+ break;
+ case 0xb:
+ strcpy(pci1ArrayPointer->type,
+ "Processors");
+ break;
+ case 0xc:
+ strcpy(pci1ArrayPointer->type,
+ "Serial bus controllers");
+ break;
+ case 0xd:
+ strcpy(pci1ArrayPointer->type,
+ "Wireless controllers");
+ break;
+ case 0xe:
+ strcpy(pci1ArrayPointer->type,
+ "Intelligent I/O controllers");
+ break;
+ case 0xf:
+ strcpy(pci1ArrayPointer->type,
+ "Satellite communication controllers");
+ break;
+ case 0x10:
+ strcpy(pci1ArrayPointer->type,
+ "Encryption/Decryption controllers");
+ break;
+ case 0x11:
+ strcpy(pci1ArrayPointer->type,
+ "Data acquisition and signal processing controllers");
+ break;
+ }
+ arrayCounter++; /* point to the next element in the Array. */
+ if (arrayCounter == numberOfElment)
+ return; /* When the Array is fully used, return. */
+ /* Else, points to next free Element. */
+ pci1ArrayPointer = &pci1Detect[arrayCounter];
+ }
+ }
+ pci1ArrayPointer->deviceNum = 0; /* 0 => End of List */
+}
+
+/********************************************************************
+* pci0WriteConfigReg - Write to a PCI configuration register
+* - Make sure the GT is configured as a master before
+* writingto another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+* Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
+* (or any other PCI device spec)
+* pciDevNum: The device number needs to be addressed.
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+
+void pci0WriteConfigReg(unsigned int regOffset, unsigned int pciDevNum,
+ unsigned int data)
+{
+ unsigned int DataForRegCf8;
+ unsigned int functionNum;
+
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0x0fffffff;
+ DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31;
+ GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8);
+ if (pciDevNum == SELF) { /* This board */
+ GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ data);
+ } else { /* configuration Transaction over the pci. */
+
+ /* The PCI is working in LE Mode So it swap the Data. */
+ GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ WORDSWAP(data));
+ }
+}
+
+/********************************************************************
+* pci1WriteConfigReg - Write to a PCI configuration register
+* - Make sure the GT is configured as a master before writing
+* to another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+* Inputs: unsigned int regOffset: The register offset as it apears in the
+* GT spec (or any other PCI device spec)
+* pciDevNum: The device number needs to be addressed.
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+
+void pci1WriteConfigReg(unsigned int regOffset, unsigned int pciDevNum,
+ unsigned int data)
+{
+ unsigned int DataForRegCf8;
+ unsigned int functionNum;
+
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0x0fffffff;
+ if (pciDevNum == SELF) { /* This board */
+ /* when configurating our own PCI 1 L-unit the access is through
+ the PCI 0 interface with reg number = reg number + 0x80 */
+ DataForRegCf8 =
+ (regOffset | pciDevNum | functionNum | 0x80) | BIT31;
+ GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8);
+ } else {
+ DataForRegCf8 =
+ (regOffset | pciDevNum | functionNum) | BIT31;
+ GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS, DataForRegCf8);
+ }
+ if (pciDevNum == SELF) { /* This board */
+ GT_REG_WRITE(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ data);
+ } else {
+ GT_REG_WRITE(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ WORDSWAP(data));
+ }
+}
+
+/********************************************************************
+* pci0ReadConfigReg - Read from a PCI0 configuration register
+* - Make sure the GT is configured as a master before
+* reading from another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
+* spec)
+* pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+* cause register to make sure the data is valid
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+
+unsigned int pci0ReadConfigReg(unsigned int regOffset,
+ unsigned int pciDevNum)
+{
+ unsigned int DataForRegCf8;
+ unsigned int data;
+ unsigned int functionNum;
+
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0x0fffffff;
+ DataForRegCf8 = (regOffset | pciDevNum | functionNum) | BIT31;
+ GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8);
+ if (pciDevNum == SELF) { /* This board */
+ GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ &data);
+ return data;
+ } else { /* The PCI is working in LE Mode So it swap the Data. */
+
+ GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ &data);
+ return WORDSWAP(data);
+ }
+}
+
+/********************************************************************
+* pci1ReadConfigReg - Read from a PCI1 configuration register
+* - Make sure the GT is configured as a master before
+* reading from another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
+* spec)
+* pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+* cause register to make sure the data is valid
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+
+unsigned int pci1ReadConfigReg(unsigned int regOffset,
+ unsigned int pciDevNum)
+{
+ unsigned int DataForRegCf8;
+ unsigned int data;
+ unsigned int functionNum;
+
+ functionNum = regOffset & 0x00000700;
+ pciDevNum = pciDevNum << 11;
+ regOffset = regOffset & 0x0fffffff;
+ if (pciDevNum == SELF) { /* This board */
+ /* when configurating our own PCI 1 L-unit the access is through
+ the PCI 0 interface with reg number = reg number + 0x80 */
+ DataForRegCf8 =
+ (regOffset | pciDevNum | functionNum | 0x80) | BIT31;
+ GT_REG_WRITE(PCI_0CONFIGURATION_ADDRESS, DataForRegCf8);
+ } else {
+ DataForRegCf8 =
+ (regOffset | pciDevNum | functionNum) | BIT31;
+ GT_REG_WRITE(PCI_1CONFIGURATION_ADDRESS, DataForRegCf8);
+ }
+ if (pciDevNum == SELF) { /* This board */
+ GT_REG_READ(PCI_0CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ &data);
+ return data;
+ } else {
+ GT_REG_READ(PCI_1CONFIGURATION_DATA_VIRTUAL_REGISTER,
+ &data);
+ return WORDSWAP(data);
+ }
+}
+
+/********************************************************************
+* pci0MapIOspace - Maps PCI0 IO space for the master.
+* Inputs: base and length of pci0Io
+*********************************************************************/
+
+void pci0MapIOspace(unsigned int pci0IoBase, unsigned int pci0IoLength)
+{
+ unsigned int pci0IoTop =
+ (unsigned int) (pci0IoBase + pci0IoLength);
+
+ if (pci0IoLength == 0)
+ pci0IoTop++;
+
+ pci0IoBase = (unsigned int) (pci0IoBase >> 21);
+ pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21);
+ GT_REG_WRITE(PCI_0I_O_LOW_DECODE_ADDRESS, pci0IoBase);
+ GT_REG_WRITE(PCI_0I_O_HIGH_DECODE_ADDRESS, pci0IoTop);
+}
+
+/********************************************************************
+* pci1MapIOspace - Maps PCI1 IO space for the master.
+* Inputs: base and length of pci1Io
+*********************************************************************/
+
+void pci1MapIOspace(unsigned int pci1IoBase, unsigned int pci1IoLength)
+{
+ unsigned int pci1IoTop =
+ (unsigned int) (pci1IoBase + pci1IoLength);
+
+ if (pci1IoLength == 0)
+ pci1IoTop++;
+
+ pci1IoBase = (unsigned int) (pci1IoBase >> 21);
+ pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21);
+ GT_REG_WRITE(PCI_1I_O_LOW_DECODE_ADDRESS, pci1IoBase);
+ GT_REG_WRITE(PCI_1I_O_HIGH_DECODE_ADDRESS, pci1IoTop);
+}
+
+/********************************************************************
+* pci0MapMemory0space - Maps PCI0 memory0 space for the master.
+* Inputs: base and length of pci0Mem0
+*********************************************************************/
+
+
+void pci0MapMemory0space(unsigned int pci0Mem0Base,
+ unsigned int pci0Mem0Length)
+{
+ unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length;
+
+ if (pci0Mem0Length == 0)
+ pci0Mem0Top++;
+
+ pci0Mem0Base = pci0Mem0Base >> 21;
+ pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21;
+ GT_REG_WRITE(PCI_0MEMORY0_LOW_DECODE_ADDRESS, pci0Mem0Base);
+ GT_REG_WRITE(PCI_0MEMORY0_HIGH_DECODE_ADDRESS, pci0Mem0Top);
+}
+
+/********************************************************************
+* pci1MapMemory0space - Maps PCI1 memory0 space for the master.
+* Inputs: base and length of pci1Mem0
+*********************************************************************/
+
+void pci1MapMemory0space(unsigned int pci1Mem0Base,
+ unsigned int pci1Mem0Length)
+{
+ unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length;
+
+ if (pci1Mem0Length == 0)
+ pci1Mem0Top++;
+
+ pci1Mem0Base = pci1Mem0Base >> 21;
+ pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21;
+ GT_REG_WRITE(PCI_1MEMORY0_LOW_DECODE_ADDRESS, pci1Mem0Base);
+ GT_REG_WRITE(PCI_1MEMORY0_HIGH_DECODE_ADDRESS, pci1Mem0Top);
+}
+
+/********************************************************************
+* pci0MapMemory1space - Maps PCI0 memory1 space for the master.
+* Inputs: base and length of pci0Mem1
+*********************************************************************/
+
+void pci0MapMemory1space(unsigned int pci0Mem1Base,
+ unsigned int pci0Mem1Length)
+{
+ unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length;
+
+ if (pci0Mem1Length == 0)
+ pci0Mem1Top++;
+
+ pci0Mem1Base = pci0Mem1Base >> 21;
+ pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21;
+ GT_REG_WRITE(PCI_0MEMORY1_LOW_DECODE_ADDRESS, pci0Mem1Base);
+ GT_REG_WRITE(PCI_0MEMORY1_HIGH_DECODE_ADDRESS, pci0Mem1Top);
+#ifndef PROM
+ DBG(KERN_INFO "pci0Mem1Base %x\n", pci0Mem1Base);
+ DBG(KERN_INFO "pci0Mem1Top %x\n", pci0Mem1Top);
+ GT_REG_READ(PCI_0MEMORY0_ADDRESS_REMAP, &pci0Mem1Base);
+ DBG(KERN_INFO "Mem 0/0 remap %x\n", pci0Mem1Base);
+ GT_REG_READ(PCI_0MEMORY1_ADDRESS_REMAP, &pci0Mem1Base);
+ DBG(KERN_INFO "Mem 0/1 remap %x\n", pci0Mem1Base);
+ GT_REG_WRITE(PCI_0MEMORY1_ADDRESS_REMAP, 0x500);
+ GT_REG_READ(PCI_0MEMORY1_ADDRESS_REMAP, &pci0Mem1Base);
+ DBG(KERN_INFO "Mem 0/1 remapped %x\n", pci0Mem1Base);
+#endif
+}
+
+/********************************************************************
+* pci1MapMemory1space - Maps PCI1 memory1 space for the master.
+* Inputs: base and length of pci1Mem1
+*********************************************************************/
+
+void pci1MapMemory1space(unsigned int pci1Mem1Base,
+ unsigned int pci1Mem1Length)
+{
+ unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length;
+
+ if (pci1Mem1Length == 0)
+ pci1Mem1Top++;
+
+ pci1Mem1Base = pci1Mem1Base >> 21;
+ pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21;
+ GT_REG_WRITE(PCI_1MEMORY1_LOW_DECODE_ADDRESS, pci1Mem1Base);
+ GT_REG_WRITE(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, pci1Mem1Top);
+}
+
+/********************************************************************
+* pci0GetIOspaceBase - Return PCI0 IO Base Address.
+* Inputs: N/A
+* Returns: PCI0 IO Base Address.
+*********************************************************************/
+
+unsigned int pci0GetIOspaceBase()
+{
+ unsigned int base;
+ GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci0GetIOspaceSize - Return PCI0 IO Bar Size.
+* Inputs: N/A
+* Returns: PCI0 IO Bar Size.
+*********************************************************************/
+
+unsigned int pci0GetIOspaceSize()
+{
+ unsigned int top, base, size;
+ GT_REG_READ(PCI_0I_O_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ GT_REG_READ(PCI_0I_O_HIGH_DECODE_ADDRESS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci0GetMemory0Base - Return PCI0 Memory 0 Base Address.
+* Inputs: N/A
+* Returns: PCI0 Memory 0 Base Address.
+*********************************************************************/
+
+unsigned int pci0GetMemory0Base()
+{
+ unsigned int base;
+ GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size.
+* Inputs: N/A
+* Returns: PCI0 Memory 0 Bar Size.
+*********************************************************************/
+
+unsigned int pci0GetMemory0Size()
+{
+ unsigned int top, base, size;
+ GT_REG_READ(PCI_0MEMORY0_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ GT_REG_READ(PCI_0MEMORY0_HIGH_DECODE_ADDRESS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci0GetMemory1Base - Return PCI0 Memory 1 Base Address.
+* Inputs: N/A
+* Returns: PCI0 Memory 1 Base Address.
+*********************************************************************/
+
+unsigned int pci0GetMemory1Base()
+{
+ unsigned int base;
+ GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size.
+* Inputs: N/A
+* Returns: PCI0 Memory 1 Bar Size.
+*********************************************************************/
+
+unsigned int pci0GetMemory1Size()
+{
+ unsigned int top, base, size;
+ GT_REG_READ(PCI_0MEMORY1_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ GT_REG_READ(PCI_0MEMORY1_HIGH_DECODE_ADDRESS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci1GetIOspaceBase - Return PCI1 IO Base Address.
+* Inputs: N/A
+* Returns: PCI1 IO Base Address.
+*********************************************************************/
+
+unsigned int pci1GetIOspaceBase()
+{
+ unsigned int base;
+ GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci1GetIOspaceSize - Return PCI1 IO Bar Size.
+* Inputs: N/A
+* Returns: PCI1 IO Bar Size.
+*********************************************************************/
+
+unsigned int pci1GetIOspaceSize()
+{
+ unsigned int top, base, size;
+ GT_REG_READ(PCI_1I_O_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ GT_REG_READ(PCI_1I_O_HIGH_DECODE_ADDRESS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci1GetMemory0Base - Return PCI1 Memory 0 Base Address.
+* Inputs: N/A
+* Returns: PCI1 Memory 0 Base Address.
+*********************************************************************/
+
+unsigned int pci1GetMemory0Base()
+{
+ unsigned int base;
+ GT_REG_READ(PCI_1MEMORY0_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size.
+* Inputs: N/A
+* Returns: PCI1 Memory 0 Bar Size.
+*********************************************************************/
+
+unsigned int pci1GetMemory0Size()
+{
+ unsigned int top, base, size;
+ GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci1GetMemory1Base - Return PCI1 Memory 1 Base Address.
+* Inputs: N/A
+* Returns: PCI1 Memory 1 Base Address.
+*********************************************************************/
+
+unsigned int pci1GetMemory1Base()
+{
+ unsigned int base;
+ GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size.
+* Inputs: N/A
+* Returns: PCI1 Memory 1 Bar Size.
+*********************************************************************/
+
+unsigned int pci1GetMemory1Size()
+{
+ unsigned int top, base, size;
+ GT_REG_READ(PCI_1MEMORY1_LOW_DECODE_ADDRESS, &base);
+ base = base << 21;
+ GT_REG_READ(PCI_1MEMORY1_HIGH_DECODE_ADDRESS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci0MapInternalRegSpace - Maps the internal registers memory space for the
+* slave.
+* Stays the same for all GT devices Disco include
+* Inputs: base of pci0 internal register
+*********************************************************************/
+
+void pci0MapInternalRegSpace(unsigned int pci0InternalBase)
+{
+ pci0InternalBase = pci0InternalBase & 0xfffff000;
+ pci0InternalBase =
+ pci0InternalBase |
+ (pci0ReadConfigReg
+ (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,
+ SELF) & 0x00000fff);
+ pci0WriteConfigReg
+ (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, SELF,
+ pci0InternalBase);
+}
+
+/********************************************************************
+* pci1MapInternalRegSpace - Maps the internal registers memory space for the
+* slave.
+* Stays the same for all GT devices Disco include
+* Inputs: base of pci1 internal register
+*********************************************************************/
+
+void pci1MapInternalRegSpace(unsigned int pci1InternalBase)
+{
+ pci1InternalBase = pci1InternalBase & 0xfffff000;
+ pci1InternalBase =
+ pci1InternalBase |
+ (pci1ReadConfigReg
+ (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS,
+ SELF) & 0x00000fff);
+ pci1WriteConfigReg
+ (PCI_0INTERNAL_REGISTERS_MEMORY_MAPPED_BASE_ADDRESS, SELF,
+ pci1InternalBase);
+}
+
+/********************************************************************
+* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the
+* slave.
+* Stays the same for all GT devices Disco include
+* Inputs: base of pci0 internal io register
+*********************************************************************/
+
+void pci0MapInternalRegIOSpace(unsigned int pci0InternalBase)
+{
+ pci0InternalBase = pci0InternalBase & 0xfffff000;
+ pci0InternalBase =
+ pci0InternalBase |
+ (pci0ReadConfigReg
+ (PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,
+ 0) & 0x00000fff);
+ pci0WriteConfigReg(PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,
+ SELF, pci0InternalBase);
+}
+
+/********************************************************************
+* pci0MapInternalRegIOSpace - Maps the internal registers IO space for the
+* slave.
+* Stays the same for all GT devices Disco include
+* Inputs: base of pci1 internal io register
+*********************************************************************/
+
+void pci1MapInternalRegIOSpace(unsigned int pci1InternalBase)
+{
+ pci1InternalBase = pci1InternalBase & 0xfffff000;
+ pci1InternalBase =
+ pci1InternalBase |
+ (pci1ReadConfigReg
+ (PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,
+ SELF) & 0x00000fff);
+ pci1WriteConfigReg(PCI_0INTERNAL_REGISTERS_I_OMAPPED_BASE_ADDRESS,
+ SELF, pci1InternalBase);
+}
+
+/********************************************************************
+* pci0MapMemoryBanks0_1 - Maps PCI0 memory banks 0 and 1 for the slave.
+* for Discovery we need two function: SCS0 & SCS1
+* (instead of SCS[1:0])
+* Inputs: base and size of pci0 dram
+*********************************************************************/
+
+
+void pci0MapMemoryBanks0_1(unsigned int pci0Dram0_1Base,
+ unsigned int pci0Dram0_1Size)
+{
+ pci0Dram0_1Base = pci0Dram0_1Base & 0xfffff000;
+ pci0Dram0_1Base =
+ pci0Dram0_1Base |
+ (pci0ReadConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF) &
+ 0x00000fff);
+ pci0WriteConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF,
+ pci0Dram0_1Base);
+ /* swapped Bar */
+ pci0WriteConfigReg(PCI_0SWAPPED_SCS_1_0_BASE_ADDRESS, SELF,
+ pci0Dram0_1Base);
+ if (pci0Dram0_1Size == 0)
+ pci0Dram0_1Size++;
+ GT_REG_WRITE(PCI_0SCS_1_0_BANK_SIZE, pci0Dram0_1Size - 1);
+}
+
+/********************************************************************
+* pci1MapMemoryBanks0_1 - Maps PCI1 memory banks 0 and 1 for the slave.
+* for Discovery we need two function: SCS0 & SCS1
+* (instead of SCS[1:0])
+* Inputs: base and size of pci1 dram
+*********************************************************************/
+
+void pci1MapMemoryBanks0_1(unsigned int pci1Dram0_1Base,
+ unsigned int pci1Dram0_1Size)
+{
+ pci1Dram0_1Base = pci1Dram0_1Base & 0xfffff000;
+ pci1Dram0_1Base =
+ pci1Dram0_1Base |
+ (pci1ReadConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF) &
+ 0x00000fff);
+ pci1WriteConfigReg(PCI_0SCS_1_0_BASE_ADDRESS, SELF,
+ pci1Dram0_1Base);
+ /* swapped Bar */
+ pci1WriteConfigReg(PCI_0SWAPPED_SCS_1_0_BASE_ADDRESS, SELF,
+ pci1Dram0_1Base);
+ if (pci1Dram0_1Size == 0)
+ pci1Dram0_1Size++;
+ GT_REG_WRITE(PCI_1SCS_1_0_BANK_SIZE, pci1Dram0_1Size - 1);
+}
+
+/********************************************************************
+* pci0MapMemoryBanks2_3 - Maps PCI0 memory banks 2 and 3 for the slave.
+* for Discovery we need two function: SCS2 & SCS3
+* (instead of SCS[3:2])
+* Inputs: base and size of pci0 dram
+*********************************************************************/
+
+void pci0MapMemoryBanks2_3(unsigned int pci0Dram2_3Base,
+ unsigned int pci0Dram2_3Size)
+{
+ pci0Dram2_3Base = pci0Dram2_3Base & 0xfffff000;
+ pci0Dram2_3Base =
+ pci0Dram2_3Base |
+ (pci0ReadConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF) &
+ 0x00000fff);
+ pci0WriteConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF,
+ pci0Dram2_3Base);
+ /* swapped Bar */
+ pci0WriteConfigReg(PCI_0SWAPPED_SCS_3_2_BASE_ADDRESS, SELF,
+ pci0Dram2_3Base);
+ if (pci0Dram2_3Size == 0)
+ pci0Dram2_3Size++;
+ GT_REG_WRITE(PCI_0SCS_3_2_BANK_SIZE, pci0Dram2_3Size - 1);
+}
+
+/********************************************************************
+* pci1MapMemoryBanks2_3 - Maps PCI1 memory banks 2 and 3 for the slave.
+* for Discovery we need two function: SCS2 & SCS3
+* (instead of SCS[3:2])
+* Inputs: base and size of pci1 dram
+*********************************************************************/
+
+void pci1MapMemoryBanks2_3(unsigned int pci1Dram2_3Base,
+ unsigned int pci1Dram2_3Size)
+{
+ pci1Dram2_3Base = pci1Dram2_3Base & 0xfffff000;
+ pci1Dram2_3Base =
+ pci1Dram2_3Base |
+ (pci1ReadConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF) &
+ 0x00000fff);
+ pci1WriteConfigReg(PCI_0SCS_3_2_BASE_ADDRESS, SELF,
+ pci1Dram2_3Base);
+ /* swapped Bar */
+ pci1WriteConfigReg(PCI_0SWAPPED_SCS_3_2_BASE_ADDRESS, SELF,
+ pci1Dram2_3Base);
+ if (pci1Dram2_3Size == 0)
+ pci1Dram2_3Size++;
+ GT_REG_WRITE(PCI_1SCS_3_2_BANK_SIZE, pci1Dram2_3Size - 1);
+}
+
+/********************************************************************
+* pci0MapDevices0_1and2MemorySpace - Maps PCI0 devices 0,1 and 2 memory spaces
+* for the slave.
+* For the Discovery there are 3 separate
+* fucnction's
+* Inputs: base and lengthof pci0 devises012
+*********************************************************************/
+
+
+void pci0MapDevices0_1and2MemorySpace(unsigned int pci0Dev012Base,
+ unsigned int pci0Dev012Length)
+{
+ pci0Dev012Base = pci0Dev012Base & 0xfffff000;
+ pci0Dev012Base =
+ pci0Dev012Base |
+ (pci0ReadConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF) &
+ 0x00000fff);
+ pci0WriteConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF, pci0Dev012Base);
+ if (pci0Dev012Length == 0)
+ pci0Dev012Length++;
+ GT_REG_WRITE(PCI_0CS_2_0_BANK_SIZE, pci0Dev012Length - 1);
+}
+
+/********************************************************************
+* pci1MapDevices0_1and2MemorySpace - Maps PCI1 devices 0,1 and 2 memory spaces
+* for the slave.
+* For the Discovery there are 3 separate
+* fucnction's
+* Inputs: base and lengthof pci1 devises012
+*********************************************************************/
+
+void pci1MapDevices0_1and2MemorySpace(unsigned int pci1Dev012Base,
+ unsigned int pci1Dev012Length)
+{
+ pci1Dev012Base = pci1Dev012Base & 0xfffff000;
+ pci1Dev012Base =
+ pci1Dev012Base |
+ (pci1ReadConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF) &
+ 0x00000fff);
+ pci1WriteConfigReg(PCI_0CS_2_0_BASE_ADDRESS, SELF, pci1Dev012Base);
+ if (pci1Dev012Length == 0)
+ pci1Dev012Length++;
+ GT_REG_WRITE(PCI_1CS_2_0_BANK_SIZE, pci1Dev012Length - 1);
+}
+
+/********************************************************************
+* pci0MapDevices3andBootMemorySpace - Maps PCI0 devices 3 and boot memory
+* spaces for the slave.
+* For the Discovery there are 2 separate
+* fucnction's
+* Inputs: base and length of pci0 device3/ boot
+*********************************************************************/
+
+void pci0MapDevices3andBootMemorySpace(unsigned int pci0Dev3andBootBase,
+ unsigned int pci0Dev3andBootLength)
+{
+ pci0Dev3andBootBase = pci0Dev3andBootBase & 0xfffff000;
+ pci0Dev3andBootBase =
+ pci0Dev3andBootBase |
+ (pci0ReadConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF) &
+ 0x00000fff);
+ pci0WriteConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF,
+ pci0Dev3andBootBase);
+ /* swapped Bar */
+ pci0WriteConfigReg(PCI_0SWAPPED_CS_3_BOOTCS_BASE_ADDRESS, SELF,
+ pci0Dev3andBootBase);
+ if (pci0Dev3andBootLength == 0)
+ pci0Dev3andBootLength++;
+ GT_REG_WRITE(PCI_0CS_3_BOOTCS_BANK_SIZE,
+ pci0Dev3andBootLength - 1);
+}
+
+/********************************************************************
+* pci1MapDevices3andBootMemorySpace - Maps PCI1 devices 3 and boot memory
+* spaces for the slave.
+* For the Discovery there are 2 separate
+* fucnction's
+* Inputs: base and length of pci1 device3/ boot
+*********************************************************************/
+
+void pci1MapDevices3andBootMemorySpace(unsigned int pci1Dev3andBootBase,
+ unsigned int pci1Dev3andBootLength)
+{
+ pci1Dev3andBootBase = pci1Dev3andBootBase & 0xfffff000;
+ pci1Dev3andBootBase =
+ pci1Dev3andBootBase |
+ (pci1ReadConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF) &
+ 0x00000fff);
+ pci1WriteConfigReg(PCI_0CS_3_BOOTCS_BASE_ADDRESS, SELF,
+ pci1Dev3andBootBase);
+ /* swapped Bar */
+ pci1WriteConfigReg(PCI_0SWAPPED_CS_3_BOOTCS_BASE_ADDRESS, SELF,
+ pci1Dev3andBootBase);
+ if (pci1Dev3andBootLength == 0)
+ pci1Dev3andBootLength++;
+ GT_REG_WRITE(PCI_1CS_3_BOOTCS_BANK_SIZE,
+ pci1Dev3andBootLength - 1);
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c b/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c
new file mode 100644
index 000000000..0d6981094
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.c
@@ -0,0 +1,318 @@
+/*
+ * 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, or (at
+ * your option) any later version.
+ */
+
+#include "etherboot.h"
+#include <asm/galileo-boards/evb64120A/pci.h>
+#include <asm/byteorder.h>
+#include "pci_etherboot.h"
+//#include "gt64120ARegs.h"
+#include "galileo_port.h"
+
+#define MAX_PCI_DEVS 10
+PCI_DEVICE pci0_devices[MAX_PCI_DEVS];
+PCI_DEVICE pci1_devices[MAX_PCI_DEVS];
+
+static int pci_range_ck(unsigned char bus, unsigned char dev)
+{
+ if ((bus == 0) && (dev >= 0) && (dev < 30))
+ return 0; // Bus/Device Number OK
+
+ return -1; // Bus/Device Number not OK
+}
+
+/********************************************************************
+ * pcibios_(read/write)_config_(byte/word/dword)
+ *
+ *Inputs :
+ *bus - bus number
+ *dev - device number
+ *offset - register offset in the configuration space
+ *val - value to be written / read
+ *
+ *Outputs :
+ *Sucees/Failure
+ *********************************************************************/
+#define PCI_CFG_DATA ((volatile unsigned long *)0xb4000cfc)
+#define PCI_CFG_CTRL ((volatile unsigned long *)0xb4000cf8)
+
+#define PCI_CFG_SET(dev,fun,off) \
+ ((*PCI_CFG_CTRL) = cpu_to_le32((0x80000000 | ((dev)<<11) | ((fun)<<8) | (off))))
+
+int pcibios_read_config_dword(unsigned char bus, unsigned char dev,
+ unsigned char offset, unsigned int *val)
+{
+
+ if (offset & 0x3) {
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+ if (pci_range_ck(bus, dev)) {
+ *val = 0xFFFFFFFF;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ PCI_CFG_SET(dev, 0, offset);
+ if (dev != 0) {
+ *val = *PCI_CFG_DATA;
+ } else {
+ *val = cpu_to_le32(*PCI_CFG_DATA);
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_read_config_word(unsigned char bus, unsigned char dev,
+ unsigned char offset, unsigned short *val)
+{
+ if (offset & 0x1)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ if (pci_range_ck(bus, dev)) {
+ *val = 0xffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ PCI_CFG_SET(dev, 0, (offset & ~0x3));
+ if (dev != 0) {
+ *val = *PCI_CFG_DATA >> ((offset & 3) * 8);
+ } else {
+ *val = cpu_to_le32(*PCI_CFG_DATA) >> ((offset & 3) * 8);
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_read_config_byte(unsigned char bus, unsigned char dev,
+ unsigned char offset, unsigned char *val)
+{
+ if (pci_range_ck(bus, dev)) {
+ *val = 0xff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ PCI_CFG_SET(dev, 0, (offset & ~0x3));
+ if (dev != 0) {
+ *val = *PCI_CFG_DATA >> ((offset & 3) * 8);
+ } else {
+ *val = cpu_to_le32(*PCI_CFG_DATA >> ((offset & 3) * 8));
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_dword(unsigned char bus, unsigned char dev,
+ unsigned char offset, unsigned int val)
+{
+ if (offset & 0x3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ if (pci_range_ck(bus, dev))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ PCI_CFG_SET(dev, 0, offset);
+ if (dev != 0) {
+ *PCI_CFG_DATA = val;
+ } else {
+ *PCI_CFG_DATA = cpu_to_le32(val);
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_word(unsigned char bus, unsigned char dev,
+ unsigned char offset, unsigned short val)
+{
+ unsigned long tmp;
+
+ if (offset & 0x1)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ if (pci_range_ck(bus, dev))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ PCI_CFG_SET(dev, 0, (offset & ~0x3));
+ if (dev != 0) {
+ tmp = *PCI_CFG_DATA;
+ } else {
+ tmp = cpu_to_le32(*PCI_CFG_DATA);
+ }
+ tmp &= ~(0xffff << ((offset & 0x3) * 8));
+ tmp |= (val << ((offset & 0x3) * 8));
+ if (dev != 0) {
+ *PCI_CFG_DATA = tmp;
+ } else {
+ *PCI_CFG_DATA = cpu_to_le32(tmp);
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_byte(unsigned char bus, unsigned char dev,
+ unsigned char offset, unsigned char val)
+{
+ unsigned long tmp;
+
+ if (pci_range_ck(bus, dev))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ PCI_CFG_SET(dev, 0, (offset & ~0x3));
+ if (dev != 0) {
+ tmp = *PCI_CFG_DATA;
+ } else {
+ tmp = cpu_to_le32(*PCI_CFG_DATA);
+ }
+ tmp &= ~(0xff << ((offset & 0x3) * 8));
+ tmp |= (val << ((offset & 0x3) * 8));
+ *PCI_CFG_DATA = cpu_to_le32(tmp);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+/********************************************************************
+ * eth_pci_init - Fill pci_devi
+ *
+ *Inputs :
+ *bus - bus number
+ *dev - device number
+ *offset - register offset in the configuration space
+ *val - value to be written / read
+ *
+ *Outputs :
+ *Sucees/Failure
+ *********************************************************************/
+void eth_pci_init(struct pci_device *pcidev)
+{
+ int i, count;
+ pcibios_write_config_word(0, 0, 4, 0x7);
+ pcibios_write_config_dword(0, 8, BAR0, 0x12000000);
+ pcibios_write_config_dword(0, 8, BAR1, 0x10000001);
+ pcibios_write_config_dword(0, 8, BAR2, 0x12100000);
+ strcpy(pci0_devices[0].type, "Network Controller");
+ pci0_devices[0].deviceNum = 8;
+ pci0_devices[0].venID = 0x8086;
+ pci0_devices[0].deviceID = 0x1229;
+
+ pci0_devices[0].bar0Base = 0x12000000;
+ pci0_devices[0].bar0Size = 0x00001000;
+ pci0_devices[0].bar0Type = 0;
+ pci0_devices[0].bar1Base = 0x10000000;
+ pci0_devices[0].bar1Size = 0x40;
+ pci0_devices[0].bar1Type = 1;
+ pci0_devices[0].bar2Base = 0x12100000;
+ pci0_devices[0].bar2Size = 0x00100000;
+ pci0_devices[0].bar2Type = 0;
+ for (i = 0; pcidev[i].vendor != 0; i++) {
+ /* Look for device in PCI0 first */
+ for (count = 0; count < MAX_PCI_DEVS; count++) {
+ if ((pci0_devices[count].type[0] != 0)
+ && ((unsigned short) pci0_devices[count].
+ venID == (unsigned short) pcidev[i].vendor)
+ && ((unsigned short) pci0_devices[count].
+ deviceID ==
+ (unsigned short) pcidev[i].dev_id)) {
+ if ((pci0_devices[count].bar0Type == 1)
+ && (pci0_devices[count].bar0Size != 0))
+ pcidev[i].ioaddr =
+ pci0_devices[count].bar0Base;
+ if ((pci0_devices[count].bar1Type == 1)
+ && (pci0_devices[count].bar1Size != 0))
+ pcidev[i].ioaddr =
+ pci0_devices[count].bar1Base;
+ if ((pci0_devices[count].bar2Type == 1)
+ && (pci0_devices[count].bar2Size != 0))
+ pcidev[i].ioaddr =
+ pci0_devices[count].bar2Base;
+ if ((pci0_devices[count].bar3Type == 1)
+ && (pci0_devices[count].bar3Size != 0))
+ pcidev[i].ioaddr =
+ pci0_devices[count].bar3Base;
+ if ((pci0_devices[count].bar4Type == 1)
+ && (pci0_devices[count].bar4Size != 0))
+ pcidev[i].ioaddr =
+ pci0_devices[count].bar4Base;
+ if ((pci0_devices[count].bar5Type == 1)
+ && (pci0_devices[count].bar5Size != 0))
+ pcidev[i].ioaddr =
+ pci0_devices[count].bar5Base;
+
+ if ((pci0_devices[count].bar0Type == 0)
+ && (pci0_devices[count].bar0Size != 0))
+ pcidev[i].membase =
+ pci0_devices[count].bar0Base;
+ if ((pci0_devices[count].bar1Type == 0)
+ && (pci0_devices[count].bar1Size != 0))
+ pcidev[i].membase =
+ pci0_devices[count].bar1Base;
+ if ((pci0_devices[count].bar2Type == 0)
+ && (pci0_devices[count].bar2Size != 0))
+ pcidev[i].membase =
+ pci0_devices[count].bar2Base;
+ if ((pci0_devices[count].bar3Type == 0)
+ && (pci0_devices[count].bar3Size != 0))
+ pcidev[i].membase =
+ pci0_devices[count].bar3Base;
+ if ((pci0_devices[count].bar4Type == 0)
+ && (pci0_devices[count].bar4Size != 0))
+ pcidev[i].membase =
+ pci0_devices[count].bar4Base;
+ if ((pci0_devices[count].bar5Type == 0)
+ && (pci0_devices[count].bar5Size != 0))
+ pcidev[i].membase =
+ pci0_devices[count].bar5Base;
+ pcidev[i].bus = 0;
+ pcidev[i].devfn =
+ pci0_devices[count].deviceNum;
+ }
+#ifdef CONFIG_EVB_PCI1
+ if ((pci1_devices[count].type[0] != 0)
+ && (pci1_devices[count].venID ==
+ pcidev[i].vendor)
+ && (pci1_devices[count].deviceID ==
+ pcidev[i].dev_id)) {
+ if ((pci1_devices[count].bar0Type == 1)
+ && (pci1_devices[count].bar0Size != 0))
+ pcidev[i].ioaddr =
+ pci1_devices[count].bar0Base;
+ if ((pci1_devices[count].bar1Type == 1)
+ && (pci1_devices[count].bar1Size != 0))
+ pcidev[i].ioaddr =
+ pci1_devices[count].bar1Base;
+ if ((pci1_devices[count].bar2Type == 1)
+ && (pci1_devices[count].bar2Size != 0))
+ pcidev[i].ioaddr =
+ pci1_devices[count].bar2Base;
+ if ((pci1_devices[count].bar3Type == 1)
+ && (pci1_devices[count].bar3Size != 0))
+ pcidev[i].ioaddr =
+ pci1_devices[count].bar3Base;
+ if ((pci1_devices[count].bar4Type == 1)
+ && (pci1_devices[count].bar4Size != 0))
+ pcidev[i].ioaddr =
+ pci1_devices[count].bar4Base;
+ if ((pci1_devices[count].bar5Type == 1)
+ && (pci1_devices[count].bar5Size != 0))
+ pcidev[i].ioaddr =
+ pci1_devices[count].bar5Base;
+
+ if ((pci1_devices[count].bar0Type == 0)
+ && (pci1_devices[count].bar0Size != 0))
+ pcidev[i].membase =
+ pci1_devices[count].bar0Base;
+ if ((pci1_devices[count].bar1Type == 0)
+ && (pci1_devices[count].bar1Size != 0))
+ pcidev[i].membase =
+ pci1_devices[count].bar1Base;
+ if ((pci1_devices[count].bar2Type == 0)
+ && (pci1_devices[count].bar2Size != 0))
+ pcidev[i].membase =
+ pci1_devices[count].bar2Base;
+ if ((pci1_devices[count].bar3Type == 0)
+ && (pci1_devices[count].bar3Size != 0))
+ pcidev[i].membase =
+ pci1_devices[count].bar3Base;
+ if ((pci1_devices[count].bar4Type == 0)
+ && (pci1_devices[count].bar4Size != 0))
+ pcidev[i].membase =
+ pci1_devices[count].bar4Base;
+ if ((pci1_devices[count].bar5Type == 0)
+ && (pci1_devices[count].bar5Size != 0))
+ pcidev[i].membase =
+ pci1_devices[count].bar5Base;
+
+ pcidev[i].bus = 1;
+ pcidev[i].devfn =
+ pci1_devices[count].deviceNum;
+ }
+#endif
+ }
+ }
+}
diff --git a/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h b/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h
new file mode 100644
index 000000000..484062bd8
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/pci_etherboot.h
@@ -0,0 +1,144 @@
+#ifndef PCI_H
+#define PCI_H
+
+/*
+** Support for NE2000 PCI clones added David Monro June 1997
+** Generalised for other PCI NICs by Ken Yap July 1997
+**
+** Most of this is taken from:
+**
+** /usr/src/linux/drivers/pci/pci.c
+** /usr/src/linux/include/linux/pci.h
+** /usr/src/linux/arch/i386/bios32.c
+** /usr/src/linux/include/linux/bios32.h
+** /usr/src/linux/drivers/net/ne.c
+*/
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2, or (at
+ * your option) any later version.
+ */
+
+#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
+#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
+#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
+
+
+#define PCI_VENDOR_ID 0x00 /* 16 bits */
+#define PCI_DEVICE_ID 0x02 /* 16 bits */
+#define PCI_COMMAND 0x04 /* 16 bits */
+
+#define PCI_CLASS_CODE 0x0b /* 8 bits */
+#define PCI_SUBCLASS_CODE 0x0a /* 8 bits */
+#define PCI_HEADER_TYPE 0x0e /* 8 bits */
+
+#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
+#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */
+#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */
+#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
+#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
+#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
+
+#ifndef PCI_BASE_ADDRESS_IO_MASK
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03)
+#endif
+#define PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define PCI_ROM_ADDRESS 0x30 /* 32 bits */
+#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM,
+ bits 31..11 are address,
+ 10..2 are reserved */
+
+#define PCI_FUNC(devfn) ((devfn) & 0x07)
+
+#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
+
+/* PCI signature: "PCI " */
+#define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
+
+/* PCI service signature: "$PCI" */
+#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
+
+#define KERN_CODE_SEG 0x8 /* This _MUST_ match start.S */
+
+#define PCI_VENDOR_ID_REALTEK 0x10ec
+#define PCI_DEVICE_ID_REALTEK_8029 0x8029
+#define PCI_DEVICE_ID_REALTEK_8139 0x8139
+#define PCI_VENDOR_ID_WINBOND2 0x1050
+#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
+#define PCI_VENDOR_ID_COMPEX 0x11f6
+#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
+#define PCI_VENDOR_ID_KTI 0x8e2e
+#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
+#define PCI_VENDOR_ID_NETVIN 0x4a14
+#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
+#define PCI_VENDOR_ID_3COM 0x10b7
+#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
+#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
+#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
+#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
+#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
+#define PCI_DEVICE_ID_3COM_3C905C_TXM 0x9200
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_DEVICE_ID_INTEL_82557 0x1229
+#define PCI_VENDOR_ID_AMD 0x1022
+#define PCI_DEVICE_ID_AMD_LANCE 0x2000
+#define PCI_VENDOR_ID_SMC_1211 0x1113
+#define PCI_DEVICE_ID_SMC_1211 0x1211
+#define PCI_VENDOR_ID_DEC 0x1011
+#define PCI_DEVICE_ID_DEC_TULIP 0x0002
+#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
+#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
+#define PCI_DEVICE_ID_DEC_21142 0x0019
+#define PCI_VENDOR_ID_SMC 0x10B8
+#ifndef PCI_DEVICE_ID_SMC_EPIC100
+# define PCI_DEVICE_ID_SMC_EPIC100 0x0005
+#endif
+#define PCI_VENDOR_ID_MACRONIX 0x10d9
+#define PCI_DEVICE_ID_MX987x5 0x0531
+#define PCI_VENDOR_ID_LINKSYS 0x11AD
+#define PCI_DEVICE_ID_LC82C115 0xC115
+#define PCI_VENDOR_ID_VIATEC 0x1106
+#define PCI_DEVICE_ID_VIA_RHINE_I 0x3043
+#define PCI_DEVICE_ID_VIA_86C100A 0x6100
+#define PCI_VENDOR_ID_DAVICOM 0x1282
+#define PCI_DEVICE_ID_DM9102 0x9102
+
+struct pci_device {
+ unsigned short vendor, dev_id;
+ const char *name;
+ unsigned int membase;
+ unsigned int ioaddr;
+ unsigned short devfn;
+ unsigned short bus;
+};
+
+extern void eth_pci_init(struct pci_device *);
+int pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char where, unsigned char *val);
+int pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char where, unsigned short *val);
+int pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char where, unsigned int *val);
+int pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char where, unsigned char val);
+int pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char where, unsigned short val);
+int pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char where, unsigned int val);
+
+/*
+ * Error values that may be returned by the PCI bios.
+ */
+#define PCIBIOS_SUCCESSFUL 0x00
+#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81
+#define PCIBIOS_BAD_VENDOR_ID 0x83
+#define PCIBIOS_DEVICE_NOT_FOUND 0x86
+#define PCIBIOS_BAD_REGISTER_NUMBER 0x87
+#define PCIBIOS_SET_FAILED 0x88
+#define PCIBIOS_BUFFER_TOO_SMALL 0x89
+
+
+
+#endif /* PCI_H */
diff --git a/arch/mips/galileo-boards/ev64120/compressed/sbd.h b/arch/mips/galileo-boards/ev64120/compressed/sbd.h
new file mode 100644
index 000000000..a5849db1f
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/sbd.h
@@ -0,0 +1,52 @@
+/*
+ * sbd.h: cpu board definitions for Galileo-9
+ * Copyright (c) 1997 Algorithmics Ltd
+ */
+
+#ifndef MHZ
+/* fastest possible pipeline clock */
+#define MHZ 150
+#endif
+
+/* FIXME These timings are completely fictional */
+#define RAMCYCLE 60 /* 60ns dram cycle */
+#define ROMCYCLE 750 /* ~750ns rom cycle */
+#define CACHECYCLE (1000/MHZ) /* internal clock */
+#define CYCLETIME CACHECYCLE
+#define CACHEMISS (CYCLETIME * 6)
+
+/*
+ * rough scaling factors for 2 instruction DELAY loop to get 1ms and 1us delays
+ */
+#define ASMDELAY(ns,icycle) \
+ (((ns) + (icycle)) / ((icycle) * 2))
+
+#define CACHEUS ASMDELAY(1000, CACHECYCLE)
+#define RAMUS ASMDELAY(1000, CACHEMISS+RAMCYCLE)
+#define ROMUS ASMDELAY(1000, CACHEMISS+ROMCYCLE)
+#define CACHEMS ASMDELAY(1000000, CACHECYCLE)
+#define RAMMS ASMDELAY(1000000, CACHEMISS+RAMCYCLE)
+#define ROMMS ASMDELAY(1000000, CACHEMISS+ROMCYCLE)
+
+#ifndef __ASSEMBLER__
+#define nsdelay(ns) mips_cycle (ASMDELAY (ns, CACHECYCLE))
+#define usdelay(us) mips_cycle (ASMDELAY ((us)*1000, CACHECYCLE))
+#endif
+
+#define DRAM_BASE 0x00000000
+#define PCI_IO_BASE 0x10000000
+#define PCI_IO_SIZE 0x02000000
+#define PCI_MEM_BASE 0x12000000
+#define PCI_MEM_SIZE 0x02000000
+#define GT64011_BASE 0x14000000
+#define DUART_BASE 0x1d000000
+#define FLASH_BASE 0x1f000000
+#define PROM_BASE 0x1fc00000
+
+
+#define LOCAL_MEM DRAM_BASE
+#define LOCAL_MEM_SIZE (128*1024*1024) /* SDRAM size (16MB) */
+
+#define BOOTPROM_BASE PROM_BASE
+
+#define DUART_CLOCK 3686400
diff --git a/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S b/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S
new file mode 100644
index 000000000..0f612aae5
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/sbdreset_evb64120A.S
@@ -0,0 +1,1054 @@
+/* $Id: sbdreset_evb64120A.S,v 1.1 2000/11/21 00:48:25 stevej Exp $ */
+/*
+** Copyright 1997 Algorithmics Ltd
+** All Rights Reserved
+**
+** gal9/sbdreset.sx -- low level board dependent routines
+*/
+
+#ifdef EVB64120A
+//#include <mips.h>
+//#include <pmon.h>
+#include <linux/config.h>
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/cacheops.h>
+#include <asm/current.h>
+#include <asm/offset.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
+#include <asm/cachectl.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/bootinfo.h>
+#include <asm/cpu.h>
+#include "sbd.h"
+
+
+#include "gt64011.h"
+#include "ns16550.h"
+
+#ifdef GALILEO_PORT // miniBios crack
+#define C0_CONFIG CP0_CONFIG
+#define C0_STATUS CP0_STATUS
+#define C0_TLBLO0 CP0_ENTRYLO0
+#define C0_TLBLO1 CP0_ENTRYLO1
+#define C0_PGMASK CP0_PAGEMASK
+#define C0_TLBHI CP0_ENTRYHI
+#define C0_INX CP0_INDEX
+#define NTLBENTRIES 48
+
+
+#define CFG_IB CONF_IB
+#define CFG_DB CONF_DB
+#define CFG_C_NONCOHERENT CONF_CM_CACHABLE_NONCOHERENT
+#define C0_SR CP0_STATUS
+#define SR_DE ST0_DE
+
+
+ #define SLEAF(x) LEAF(x)
+ #define SEND(x) END(x)
+ #define XLEAF(x) LEAF(x)
+ #define SBD_DISPLAY(a,b,c,d,e) ;
+
+#define K0BASE 0x80000000
+#define K0SIZE 0x20000000
+#define K1BASE 0xa0000000
+#define K1SIZE 0x20000000
+#define K2BASE 0xc0000000
+
+#define PHYS_TO_K0(pa) ((pa)|K0BASE)
+#define PHYS_TO_K1(pa) ((pa)|K1BASE)
+#define K0_TO_PHYS(va) ((va)&(K0SIZE-1))
+#define K1_TO_PHYS(va) ((va)&(K1SIZE-1))
+#define K0_TO_K1(va) ((va)|K1SIZE)
+#define K1_TO_K0(va) ((va)&~K1SIZE)
+
+#define PA_TO_KVA0(pa) PHYS_TO_K0(pa)
+#define PA_TO_KVA1(pa) PHYS_TO_K1(pa)
+#define KVA_TO_PA(pa) K1_TO_PHYS(pa)
+#define KSEG0_BASE K0BASE
+#define KSEG1_BASE K1BASE
+
+
+#endif
+
+#define MB 0x100000
+
+#define MemTypeNone 0x8000
+#define MemRasMask 0x0f00
+#define MemRasShift 8
+#define MemCasMask 0x000f
+#define MemCasShift 0
+
+#define rasave s0
+#define p64011 s1
+#define bank0 s2
+#define bank1 s3
+#define bank2 s4
+#define bank3 s5
+#define memtop s6
+#define membase s7
+
+/*#if #endian(big) */
+#ifdef __MIPSEB__
+
+#define HTOLL(sr,tr) \
+ .set noat ; \
+ srl AT,sr,24 ; \
+ srl tr,sr,8 ; \
+ and tr,0xff00 ; \
+ or AT,tr ; \
+ and tr,sr,0xff00 ; \
+ sll tr,8 ; \
+ or AT,tr ; \
+ sll tr,sr,24 ; \
+ or sr,AT,tr ; \
+ .set at
+#else
+#define HTOLL(sr,tr)
+#endif
+
+#undef DBGSBD
+
+#ifdef DBGSBD
+#define DBG(s) \
+ .rdata ; \
+88: .asciiz s ; \
+ .text ; \
+ la a0, 88b ; \
+ jal _dbgmsg
+
+LEAF(_dbgmsg)
+ .set noat
+ li AT,PHYS_TO_K1(NS16550_CHANB)
+waitrdy:
+ lbu v1,LSR(AT)
+ .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+ and v1,LSR_TXRDY
+ beqz v1,waitrdy
+
+ lbu v1,(a0)
+ addu a0,1
+ beqz v1,9f
+ sb v1,DATA(AT)
+ .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+ b waitrdy
+9: j ra
+ .set at
+END(_dbgmsg)
+
+LEAF(_dbghex)
+ li a1,PHYS_TO_K1(NS16550_CHANB)
+ li t0,8
+1:
+ lbu t1,LSR(a1)
+ .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+ and t1,LSR_TXRDY
+ beqz t1,1b
+
+ srl t1,a0,28
+ addu t1,'0'
+ ble t1,'9',2f
+ addu t1,'a'-'0'-10
+2: sb t1,DATA(a1)
+ .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+
+ sll a0,4
+ sub t0,1
+ bnez t0,1b
+
+ j ra
+ .set at
+END(_dbghex)
+
+ .rdata
+initb_str:
+ .byte 9,0x40 /* Reset CH B */
+ .byte 1,0x00 /* Interrupt disabled */
+ .byte 3,0xc1 /* 8 bits/char rx enable */
+ .byte 4,0x44 /* x16 clk mode 1 stop bit */
+ .byte 5,0x6a /* tx 8/bit RTS & tx enable */
+ .byte 9,0x0a /* MIE Master int enab. and NV No Vector */
+ .byte 11,0x50 /* Select BR gen. out for both rx and ts */
+ .byte 0,0x10
+ .byte 0,0x10
+ .byte 14,0x01 /* enable baud rate gen. */
+ .byte 15,0x00 /* known state for reg 15 */
+
+ .byte 14,0x00 /* disable baud rate gen. */
+ .byte 12,0x0a /* 0x0a = 9600 baud time const. - lower 8 bits */
+ .byte 13,0x00 /* 9600 buad time const. - upper 8 bits */
+ .byte 14,0x01 /* enable baud rate gen. */
+ .byte 0xff
+
+ .text
+
+SLEAF(_dbginit)
+ /*
+ li v0,PHYS_TO_K1(NS16550_CHANB)
+ la a0,initb_str
+ or a0,K1BASE
+1: lbu t0,0(a0)
+ beq t0,0xff,1f
+ sb t0,LSR(v0)
+ .set noreorder; nop; nop; nop; nop; nop; nop; nop; nop; .set reorder
+ addu a0,1
+ b 1b
+ */
+ jal init_ns16550_chan_b # Debug channel
+ j ra
+SEND(_dbginit)
+#else
+#define DBG(s)
+#endif
+
+LEAF(sbdreset)
+ move rasave,ra
+
+ /* if launched by ITROM, leave Config alone */
+#ifndef ITBASE
+ /* set config register for 32b/32b cachelines, kseg0 cacheable */
+ mfc0 t1,C0_CONFIG
+ and t1,~0x3f # set bits 5..0 only
+ or t1,CFG_IB | CFG_DB | CFG_C_NONCOHERENT
+ mtc0 t1,C0_CONFIG
+#endif
+
+ /* Initialize stack pointer to 6MB address */
+ li sp,0xa0600000
+
+
+ /*
+ * slight amount of kludgery here to stop RAM resident
+ * program from overwriting itself...
+ */
+// li v1,0x1fc00000 /* check return address is in ROM */
+// and v0,ra,v1
+// bne v0,v1,.noinit
+
+ /* table driven hardware register initialization */
+ la a0, reginittab
+ or a0, K1BASE /* force to kseg1 */
+
+1: lw v0,0(a0)
+ lw v1,4(a0)
+ addu a0,8
+ beqz v0,8f
+
+ sw v1,0(v0)
+ b 1b
+8:
+
+#ifdef DBGSBD
+ jal init_ns16550_chan_b # was - _dbginit
+ DBG("sbdreset\r\n")
+#endif
+#define DEVICE_BANK0PARAMETERS 0x45C
+#define DEVICE_BANK1PARAMETERS 0x460
+#define DEVICE_BANK2PARAMETERS 0x464
+#define DEVICE_BANK3PARAMETERS 0x468
+#define DEVICE_BOOT_BANK_PARAMETERS 0x46C
+#define GT_INTERNAL_REG_BASE 0xb4000000
+
+ li p64011, PA_TO_KVA1(GT64011_BASE)
+
+ li v0,0xb400046c /* Boot Device */
+ lw t0,0(v0)
+ and t0,0x00003000 /* Keep the correct boot size */
+ or t0,htoll(0x3847de70)
+ sw t0,0(v0)
+
+ li v0,0xb4000468 /* CS3 Device - 16 bit FLASH memory */
+ li t0,htoll(0x3859e6e8)
+ sw t0,0(v0)
+
+
+ li v0,0xb4000c84 /* PCI 1 timeout register */
+ li t0,htoll(0xffff)
+ sw t0,0(v0)
+
+
+ li v0,0xb4000c3c /* Enable I/O response on PCI0 */
+ li t0,htoll(0x7)
+ sw t0,0(v0)
+
+ li v0,0xb4000cbc /* Enable I/O response on PCI1 */
+ li t0,htoll(0x7)
+ sw t0,0(v0)
+
+ /* GT-64120 Initialization */
+
+ li p64011, PA_TO_KVA1(GT64011_BASE)
+
+ /*********************************************************************/
+ /************************* SDRAM initializing ************************/
+ /******************************* START *******************************/
+
+
+ /* SDRAM banks 0,1,2,3 parameters */
+ li t0,htoll(0x01908200) /* - Standard Monitor: Interleave enabled */
+ li v0,0xb4000448 /* - Registered SDRAM (Bit 23) */
+ sw t0,0(v0) /* - Duplicate Dadr11,BankSel1 and Dadr12 */
+ /* - Cas latency: 2 Cycles */
+ /* - Flow Through enable: One sample */
+ /* - SRAS - precharge time: 3 Cycles */
+ /* - No ECC */
+ /* - No ByPass */
+ /* - Burst length: 8 */
+
+ /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM0 */
+ /* Set bank0`s range to: 0 - 0x10000000 (256 MByte) */
+_DIMM0:
+ li v0,0xb4000008
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+
+ li v0,0xb4000010
+ li t0,htoll(0x7f)
+ sw t0,0(v0)
+
+ /* Close banks 2 and 3 */
+ li v0,0xb4000018
+ li t0,htoll(0x7ff)
+ sw t0,0(v0)
+ li v0,0xb4000020
+ li t0,htoll(0x00)
+ sw t0,0(v0)
+
+ /* Extend bank0 to 0x10000000 and Close bank1,2 and 3 */
+ DBG("Extend bank0 to 0x10000000 and Close bank1,2 and 3...\r\n")
+ li v0,0xb4000400
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+ li v0,0xb4000404
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+ li v0,0xb4000408
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+ li v0,0xb400040c
+ li t0,htoll(0x00)
+ sw t0,0(v0)
+ li v0,0xb4000410
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+ li v0,0xb4000414
+ li t0,htoll(0x00)
+ sw t0,0(v0)
+ li v0,0xb4000418
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+ li v0,0xb400041c
+ li t0,htoll(0x00)
+ sw t0,0(v0)
+
+ /* Configure bank0 to 256 Mbit */
+ DBG("Configure bank0 to 256 Mbit...\r\n")
+ li v0,0xb400044c
+ li t0,htoll(0x00004c69)
+ sw t0,0(v0)
+
+ /* Config the SDRAM banks decode system */
+ li v0,0xb400047c
+ li t0,htoll(2)
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x3)
+ sw t0,0(v0)
+
+ li v0,0xa0000000
+ li t0,0
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+
+ /* Write to address 0x2000000 and check if 0x00000000 is being written too */
+ DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n")
+ li v0,0xa0000000
+ li t1,0xa0000010
+ li t0,htoll(0x0)
+1: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,1b
+
+ /* The address should activate Dadr12 */
+ li v0,0xa2000000
+ li t0,0x11111111
+ sw t0,0(v0)
+ li v0,0xa0000010
+ li t1,0xa0000100
+ li t0,0x22222222
+2: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,2b
+
+ DBG("Check address 0x00000000 for duplications...\r\n")
+ li t0,0xa0000000
+ li v0,0x11111111
+ lw t0,(t0)
+ bne t0,v0,_256MBIT
+
+ /* Write to address 0x1000 and check if 0x00000000 is being written too */
+ DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n")
+ li v0,0xa0000000
+ li t1,0xa0000010
+ li t0,htoll(0x0)
+1: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,1b
+
+ /* The address should activate bank select1*/
+ li v0,0xa0001000
+ li t0,0x11111111
+ sw t0,0(v0)
+ li v0,0xa0000010
+ li t1,0xa0000100
+ li t0,0x22222222
+2: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,2b
+
+ DBG("Check address 0x00000000 for duplications...\r\n")
+ li t0,0xa0000000
+ li v0,0x11111111
+ lw t0,(t0)
+ beq t0,v0,_16MBIT
+
+ /* Write to address 0x8000000 and check if 0x00000000 is being written too */
+ DBG("Write to address 0x8000000 and check if 0x00000000 is being written too...\r\n")
+ li v0,0xa0000000
+ li t1,0xa0000010
+ li t0,htoll(0x0)
+1: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,1b
+
+ /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit
+ device */
+ li v0,0xa8000000
+ li t0,0x11111111
+ sw t0,0(v0)
+ li v0,0xa0000010
+ li t1,0xa0000100
+ li t0,0x22222222
+2: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,2b
+
+ DBG("Check address 0x00000000 for duplications...\r\n")
+ li t0,0xa0000000
+ li v0,0x11111111
+ lw t0,(t0)
+ beq t0,v0,_64MBIT
+ b _128MBIT
+
+_16MBIT:
+ DBG("16 Mbit SDRAM detected...\r\n")
+ /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */
+ li v0,0xb4000810
+ li t0,htoll(16)
+ sw t0,0(v0)
+ li t1,htoll(0x00000449)
+ b _DIMM1
+
+_64MBIT:
+ DBG("64 Mbit SDRAM detected...\r\n")
+ /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */
+ li v0,0xb4000810
+ li t0,htoll(64)
+ sw t0,0(v0)
+ li t1,htoll(0x00000c69)
+ b _DIMM1
+
+_128MBIT:
+ DBG("128 Mbit SDRAM detected...\r\n")
+ /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */
+ li v0,0xb4000810
+ li t0,htoll(128)
+ sw t0,0(v0)
+ li t1,htoll(0x00000c69)
+ b _DIMM1
+
+_256MBIT:
+ DBG("256 Mbit SDRAM detected...\r\n")
+ /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */
+ li v0,0xb4000810
+ li t0,htoll(256)
+ sw t0,0(v0)
+ li t1,htoll(0x00004c69)
+ b _DIMM1
+
+_DIMM1:
+ li v0,0xb400044c
+ sw t1,0(v0) # Bank0
+ sw t1,4(v0) # Bank1
+
+ /* Detect whether we have a 16,64,128 or 256 Mbit SDRAM on DIMM1 */
+ /* Close banks 0 and 1 */
+ li v0,0xb4000008
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+
+ li v0,0xb4000010
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+
+ /* Set bank2`s range to: 0 - 0x10000000 (256 MByte) */
+ li v0,0xb4000018
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+ li v0,0xb4000020
+ li t0,htoll(0x7f)
+ sw t0,0(v0)
+
+ /* Extend bank2 to 0x10000000 and Close bank0,1 and 3 */
+ DBG("Extend bank2 to 0x10000000 and Close banks 0,1 and 3...\r\n")
+ li v0,0xb4000400
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+ li v0,0xb4000404
+ li t0,htoll(0x00)
+ sw t0,0(v0)
+ li v0,0xb4000408
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+ li v0,0xb400040c
+ li t0,htoll(0x00)
+ sw t0,0(v0)
+ li v0,0xb4000410
+ li t0,htoll(0x00)
+ sw t0,0(v0)
+ li v0,0xb4000414
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+ li v0,0xb4000418
+ li t0,htoll(0xff)
+ sw t0,0(v0)
+ li v0,0xb400041c
+ li t0,htoll(0x00)
+ sw t0,0(v0)
+
+ /* Configure bank2 to 256 Mbit */
+ DBG("Configure bank2 to 256 Mbit...\r\n")
+ li v0,0xb4000454
+ li t0,htoll(0x00004c69)
+ sw t0,0(v0)
+
+ /* Config the SDRAM banks decode system */
+ li v0,0xb400047c
+ li t0,htoll(2)
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x3)
+ sw t0,0(v0)
+
+ li v0,0xa0000000
+ li t0,0
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+
+ /* Write to address 0x2000000 and check if 0x00000000 is being written too */
+ DBG("Write to address 0x2000000 and check if 0x00000000 is being written too...\r\n")
+ li v0,0xa0000000
+ li t1,0xa0000010
+ li t0,htoll(0x0)
+1: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,1b
+
+ /* The address should activate Dadr12 */
+ li v0,0xa2000000
+ li t0,0x11111111
+ sw t0,0(v0)
+ li v0,0xa0000010
+ li t1,0xa0000100
+ li t0,0x22222222
+2: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,2b
+
+ DBG("Check address 0x00000000 for duplications...\r\n")
+ li t0,0xa0000000
+ li v0,0x11111111
+ lw t0,(t0)
+ bne t0,v0,_256MBIT2
+
+ /* Write to address 0x1000 and check if 0x00000000 is being written too */
+ DBG("Write to address 0x1000 and check if 0x00000000 is being written too...\r\n")
+ li v0,0xa0000000
+ li t1,0xa0000010
+ li t0,htoll(0x0)
+1: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,1b
+
+ /* The address should activate bank select1*/
+ li v0,0xa0001000
+ li t0,0x11111111
+ sw t0,0(v0)
+ li v0,0xa0000010
+ li t1,0xa0000100
+ li t0,0x22222222
+2: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,2b
+
+ DBG("Check address 0x00000000 for duplications...\r\n")
+ li t0,0xa0000000
+ li v0,0x11111111
+ lw t0,(t0)
+ beq t0,v0,_16MBIT2
+
+ /* Write to address 0x8000000 and check if 0x00000000 is being written too */
+ DBG("Write to address 0x8000000 and check if 0x00000000 is being written too...\r\n")
+ li v0,0xa0000000
+ li t1,0xa0000010
+ li t0,htoll(0x0)
+1: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,1b
+
+ /* The address should activate Dadr9 which on the column cycle is in active with 64 Mbit
+ device */
+ li v0,0xa8000000
+ li t0,0x11111111
+ sw t0,0(v0)
+ li v0,0xa0000010
+ li t1,0xa0000100
+ li t0,0x22222222
+2: sw t0,0(v0)
+ addu v0,4
+ bne t1,v0,2b
+
+ DBG("Check address 0x00000000 for duplications...\r\n")
+ li t0,0xa0000000
+ li v0,0x11111111
+ lw t0,(t0)
+ beq t0,v0,_64MBIT2
+ b _128MBIT2
+
+_16MBIT2:
+ DBG("16 Mbit SDRAM detected...\r\n")
+ /* In 16 Mbit SDRAM we must use 2 way bank interleaving!!! */
+ li v0,0xb4000814
+ li t0,htoll(16)
+ sw t0,0(v0)
+ li t1,htoll(0x00000449)
+ b _INIT_SDRAM
+
+_64MBIT2:
+ DBG("64 Mbit SDRAM detected...\r\n")
+ /* In 64 Mbit SDRAM we must use 4 way bank interleaving!!! */
+ li v0,0xb4000814
+ li t0,htoll(64)
+ sw t0,0(v0)
+ li t1,htoll(0x00000c69)
+ b _INIT_SDRAM
+
+_128MBIT2:
+ DBG("128 Mbit SDRAM detected...\r\n")
+ /* In 128 Mbit SDRAM we must use 4 way bank interleaving!!! */
+ li v0,0xb4000814
+ li t0,htoll(128)
+ sw t0,0(v0)
+ li t1,htoll(0x00000c69)
+ b _INIT_SDRAM
+
+_256MBIT2:
+ DBG("256 Mbit SDRAM detected...\r\n")
+ /* In 256 Mbit SDRAM we must use 4 way bank interleaving!!! */
+ li v0,0xb4000814
+ li t0,htoll(256)
+ sw t0,0(v0)
+ li t1,htoll(0x00004c69)
+ b _INIT_SDRAM
+
+_INIT_SDRAM:
+ /* Restore defaults */
+ DBG("Restoring defaults...\r\n")
+ li v0,0xb4000404
+ li t0,htoll(0x07)
+ sw t0,0(v0)
+ li v0,0xb4000408
+ li t0,htoll(0x08)
+ sw t0,0(v0)
+ li v0,0xb400040c
+ li t0,htoll(0x0f)
+ sw t0,0(v0)
+ li v0,0xb4000410
+ li t0,htoll(0x10)
+ sw t0,0(v0)
+ li v0,0xb4000414
+ li t0,htoll(0x17)
+ sw t0,0(v0)
+ li v0,0xb4000418
+ li t0,htoll(0x18)
+ sw t0,0(v0)
+ li v0,0xb400041c
+ li t0,htoll(0x1f)
+ sw t0,0(v0)
+ li v0,0xb4000010
+ li t0,htoll(0x07)
+ sw t0,0(v0)
+ li v0,0xb4000018
+ li t0,htoll(0x008)
+ sw t0,0(v0)
+ li v0,0xb4000020
+ li t0,htoll(0x0f)
+ sw t0,0(v0)
+
+ li v0,0xb400044c
+ sw t1,8(v0) # Bank2
+ sw t1,12(v0) # Bank3
+
+ li v0,0xb4000474
+ li t0,htoll(0x3)
+ sw t0,0(v0)
+
+ li v0,0xa0000000
+ li t0,0
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x3)
+ sw t0,0(v0)
+
+ li v0,0xa0800000
+ li t0,0
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x3)
+ sw t0,0(v0)
+
+ li v0,0xa1000000
+ li t0,0
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x3)
+ sw t0,0(v0)
+
+ li v0,0xa1800000
+ li t0,0
+ sw t0,0(v0)
+
+ li v0,0xb4000474
+ li t0,htoll(0x0)
+ sw t0,0(v0)
+
+ /*********************************************************************/
+ /************************* SDRAM initializing ************************/
+ /******************************* END *********************************/
+
+ li p64011, PA_TO_KVA1(GT64011_BASE)
+
+ li t0,htoll(0x00000000) /* RAS[1:0] low decode address */
+ sw t0,0x008(p64011)
+
+ li t0,htoll(0x00000007) /* RAS[1:0] high decode address */
+ sw t0,0x010(p64011)
+
+ li t0,htoll(0x00000000) /* RAS[0] Low decode address */
+ sw t0,0x400(p64011)
+
+ li t0,htoll(0x0000000f) /* RAS[0] High decode address */
+ sw t0,0x404(p64011)
+
+ li t0,htoll(0x00000008) /* RAS[3:2] low decode address */
+ sw t0,0x018(p64011)
+
+ li t0,htoll(0x0000000f) /* RAS[3:2] high decode address */
+ sw t0,0x020(p64011)
+
+ li t0,htoll(0x0000000f) /* RAS[1] Low Decode Address */
+ sw t0,0x408(p64011)
+
+ li t0,htoll(0x00000008) /* RAS[1] High Decode Address */
+ sw t0,0x40c(p64011)
+
+ li t0,htoll(0x00000010) /* RAS[2] Low Decode Address */
+ sw t0,0x410(p64011)
+
+ li t0,htoll(0x00000017) /* RAS[2] High Decode Address */
+ sw t0,0x414(p64011)
+
+ li t0,htoll(0x00000018) /* RAS[3] Low Decode Address */
+ sw t0,0x418(p64011)
+
+ li t0,htoll(0x0000001f) /* RAS[3] High Decode Address <<<<<< 1*/
+ sw t0,0x41c(p64011)
+
+#ifdef DBGSBD
+#define DREG(str,rname) \
+ DBG(str); \
+ DBG(":\t") ; \
+ lw a0,rname(p64011) ; \
+ HTOLL(a0,t0) ; \
+ jal _dbghex ; \
+ DBG("\r\n")
+
+ DBG("GT-64120 settings:\r\n")
+ DREG("DRAMPAR_BANK0 (44c)",GT_DRAMPAR_BANK0)
+ DREG("DRAMPAR_BANK1 (450)",GT_DRAMPAR_BANK1)
+ DREG("DRAMPAR_BANK2 (454)",GT_DRAMPAR_BANK2)
+ DREG("DRAMPAR_BANK3 (458)",GT_DRAMPAR_BANK3)
+ DREG("PAS_RAS10LO (008)",GT_PAS_RAS10LO)
+ DREG("PAS_RAS10HI (010)",GT_PAS_RAS10HI)
+ DREG("PAS_RAS32LO (018)",GT_PAS_RAS32LO)
+ DREG("PAS_RAS32HI (020)",GT_PAS_RAS32HI)
+ DREG("DDAS_RAS0LO (400)",GT_DDAS_RAS0LO)
+ DREG("DDAS_RAS0HI (404)",GT_DDAS_RAS0HI)
+ DREG("DDAS_RAS1LO (408)",GT_DDAS_RAS1LO)
+ DREG("DDAS_RAS1HI (40c)",GT_DDAS_RAS1HI)
+ DREG("DDAS_RAS2LO (410)",GT_DDAS_RAS2LO)
+ DREG("DDAS_RAS2HI (414)",GT_DDAS_RAS2HI)
+ DREG("DDAS_RAS3LO (418)",GT_DDAS_RAS3LO)
+ DREG("DDAS_RAS3HI (41c)",GT_DDAS_RAS3HI)
+ DREG("GT_DRAM_CFG (448)",GT_DRAM_CFG)
+ DREG("GT_DEVPAR_BANK0 (45c)",GT_DEVPAR_BANK0)
+ DREG("GT_DEVPAR_BANK1 (460)",GT_DEVPAR_BANK1)
+ DREG("GT_DEVPAR_BANK2 (464)",GT_DEVPAR_BANK2)
+ DREG("GT_DEVPAR_BANK3 (468)",GT_DEVPAR_BANK3)
+ DREG("GT_IPCI_TOR (c04)",GT_IPCI_TOR)
+#endif
+
+ /* we can now initialise the caches for a fast clear_mem */
+ SBD_DISPLAY ('C','A','C','H',CHKPNT_CACH)
+ DBG("init_cache\r\n")
+// jal mips_init_cache
+
+.noinit:
+
+ /* initialise tlb */
+ SBD_DISPLAY ('I','T','L','B', CHKPNT_ITLB)
+ DBG("init_tlb\r\n")
+// bal init_tlb
+
+// DBG("sbdreset completed\r\n")
+// move ra,rasave
+ j GetExtendedMemorySize
+ nop
+
+END(sbdreset)
+
+LEAF(_sbd_memfail)
+ SBD_DISPLAY ('!','M','E','M',CHKPNT_0MEM)
+1: b 1b
+ j ra
+END(_sbd_memfail)
+
+ .rdata
+RefreshBits:
+ .word htoll(GT_DRAMPAR_Refresh512)
+ .word htoll(GT_DRAMPAR_Refresh1024)
+ .word htoll(GT_DRAMPAR_Refresh2048)
+ .word htoll(GT_DRAMPAR_Refresh4096)
+ .text
+
+/* DRAM: */
+#define GT_DRAM_CFG_INIT \
+ GT_DRAM_CFG_RefIntCnt(160) | \
+ GT_DRAM_CFG_StagRefOn | \
+ GT_DRAM_CFG_ADSFunctDRAM | \
+ GT_DRAM_CFG_DRAMLatchActive
+
+/* serial port: widest timings even 8 bit bus, latch enabled no parity */
+#define GT_DEVPAR_SERIALINIT \
+ GT_DEVPAR_TurnOff(7) | \
+ GT_DEVPAR_AccToFirst(15) | \
+ GT_DEVPAR_AccToNext(15) | \
+ GT_DEVPAR_ADStoWr(7) | \
+ GT_DEVPAR_WrActive(7) | \
+ GT_DEVPAR_WrHigh(7) | \
+ GT_DEVPAR_DevWidth8 | \
+ GT_DEVPAR_DevLocEven | \
+ GT_DEVPAR_LatchFunctTransparent | \
+ GT_DEVPAR_ParityDisable | \
+ GT_DEVPAR_Reserved
+
+/* PCI: */
+#define GT_IPCI_TOR_INIT \
+ GT_IPCI_TOR_Timeout0(255) | \
+ GT_IPCI_TOR_Timeout1(255) | \
+ GT_IPCI_TOR_RetryCtr(0)
+
+#define INIT(addr,val) \
+ .word addr, val
+#define GTINIT(addr,val) \
+ INIT(PHYS_TO_K1(GT64011_BASE+(addr)), htoll(val))
+
+ .rdata
+reginittab:
+
+ /* disable ras1:0 and ras3:2 decodes */
+ GTINIT(GT_PAS_RAS10LO, GT_PAS_LOMASK_Low);
+ GTINIT(GT_PAS_RAS10HI, 0);
+ GTINIT(GT_PAS_RAS32LO, GT_PAS_LOMASK_Low);
+ GTINIT(GT_PAS_RAS32HI, 0);
+
+ /* disable RAS[0123] */
+ GTINIT(GT_DDAS_RAS0LO, GT_DDAS_LOMASK_Low)
+ GTINIT(GT_DDAS_RAS0HI, 0);
+ GTINIT(GT_DDAS_RAS1LO, GT_DDAS_LOMASK_Low)
+ GTINIT(GT_DDAS_RAS1HI, 0);
+ GTINIT(GT_DDAS_RAS2LO, GT_DDAS_LOMASK_Low)
+ GTINIT(GT_DDAS_RAS2HI, 0);
+ GTINIT(GT_DDAS_RAS3LO, GT_DDAS_LOMASK_Low)
+ GTINIT(GT_DDAS_RAS3HI, 0);
+
+ /* 0x45c, 0x460, 0x464, 0x468 */
+ /*GTINIT(GT_DEVPAR_BANK0, GT_DEVPAR_SERIALINIT)*/
+ GTINIT(GT_DEVPAR_BANK0, 0x3847de60)
+ GTINIT(GT_DEVPAR_BANK1, 0x146fffff)
+ GTINIT(GT_DEVPAR_BANK2, 0x144fffff)
+ GTINIT(GT_DEVPAR_BANK3, 0x167fffff)
+
+ GTINIT(GT_IPCI_TOR, GT_IPCI_TOR_INIT)
+ INIT(0,0)
+ .text
+
+ .globl sbddelay
+
+LEAF(sbdberrenb)
+ mfc0 v0,C0_SR
+ li t0,SR_DE
+ bnez a0,1f
+ or t1,v0,t0 # disable cache/parity errors (SR_DE = 1)
+ b 2f
+1: not t1,t0 # enable cache/parity errors (SR_DE = 0)
+ and t1,v0
+2: mtc0 t1,C0_SR
+ and v0,t0 # get old SR_DE bit
+ xor v0,t0 # and invert to make it an enable bit
+ j ra
+END(sbdberrenb)
+
+
+LEAF(sbdberrcnt)
+ move v0,zero
+ j ra
+END(sbdberrcnt)
+
+ .lcomm wbfltmp,4
+
+LEAF(wbflush)
+//XLEAF(mips_wbflush)
+ sync
+ la t0,wbfltmp
+ or t0,K1BASE
+ lw zero,0(t0)
+ j ra
+END(wbflush)
+
+
+LEAF(sbddelay)
+ li t1,CACHEUS
+ and t0,ra,0x20000000
+ beqz t0,1f
+ li t1,ROMUS
+1: mul a0,t1
+ subu a0,15 # approx number of loops so far
+
+ .set noreorder
+ .set nomacro
+ nop
+2: bgtz a0,2b
+ subu a0,1
+ .set macro
+ .set reorder
+
+ j ra
+END(sbddelay)
+
+#include "meminit.S"
+
+
+LEAF(mips_cycle)
+ .set noreorder
+ .set nomacro
+1: bgtz a0,1b
+ subu a0,1
+ .set macro
+ .set reorder
+ j ra
+END(mips_cycle)
+
+LEAF(init_ns16550_chan_b)
+ # enable 16550 fifo if it is there
+ li a0,NS16550_CHANB
+ li t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
+ sb t0,FIFO(a0)
+
+ /* convert baud rate in a1 into register value */
+ li t2,NS16550_HZ/(16*115200) # brtc = CLK/16/speed
+
+ li t0,CFCR_DLAB # select brtc divisor
+ sb t0,CFCR(a0)
+ sb t2,DATA(a0) # store divisor lsb
+ srl t2,8
+ sb t2,IER(a0) # store divisor msb
+
+ li t0,CFCR_8BITS # set 8N1 mode
+ sb t0,CFCR(a0)
+
+ li t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE # enable DTR & RTS
+ sb t0,MCR(a0)
+ li t0,0 # Galileo IER_ERXRDY # enable receive interrupt(!)
+ sb t0,IER(a0)
+
+ move v0,zero # indicate success
+ j ra
+
+END(init_ns16550_chan_b)
+
+LEAF(init_ns16550_chan_a)
+ # enable 16550 fifo if it is there
+ li a0,NS16550_CHANA
+ li t0,FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
+ sb t0,FIFO(a0)
+
+ /* convert baud rate in a1 into register value */
+ li t2,NS16550_HZ/(16*9600) # brtc = CLK/16/speed
+
+ li t0,CFCR_DLAB # select brtc divisor
+ sb t0,CFCR(a0)
+ sb t2,DATA(a0) # store divisor lsb
+ srl t2,8
+ sb t2,IER(a0) # store divisor msb
+
+ li t0,CFCR_8BITS # set 8N1 mode
+ sb t0,CFCR(a0)
+
+ li t0,MCR_DTR|MCR_RTS # Galileo |MCR_IENABLE # enable DTR & RTS
+ sb t0,MCR(a0)
+ li t0,0 # Galileo IER_ERXRDY # enable receive interrupt(!)
+ sb t0,IER(a0)
+
+ move v0,zero # indicate success
+ j ra
+
+END(init_ns16550_chan_a)
+
+#endif /* EVB64120A */
diff --git a/arch/mips/galileo-boards/ev64120/compressed/xfer.c b/arch/mips/galileo-boards/ev64120/compressed/xfer.c
new file mode 100644
index 000000000..15c6c49fd
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/compressed/xfer.c
@@ -0,0 +1,114 @@
+/*
+ * arch/mips/galileo/compressed/xfer.c
+ *
+ * By RidgeRun Inc,
+ *
+ * Xfer an image from flash to ram.
+ * For use with Galileo EVB64120A MIPS eval board.
+ */
+
+#include "linux/serial_reg.h"
+
+#define port 0xbd000000
+#define inb(addr) (*(volatile unsigned char *) ((unsigned long)(addr)))
+#define outb(b,addr) (*(volatile unsigned char *) ((unsigned long)(addr)) = (b))
+
+#ifdef RUNNINGFROMFLASH
+// This is where our image of interest is mapped to
+// when the jumbers are set for booting out of flash.
+// (flash part starts at address 0xbfC00000)
+#define srcAddr 0xbfC20000
+#else
+// This is where our image of interest is mapped to
+// when the jumbers are set for booting out of eprom.
+// (flash part starts at address 0xbf000000)
+#define srcAddr 0xbf020000
+#endif
+
+static int PortAddress(unsigned int channel, unsigned char reg);
+static void inline cons_hook(void);
+static void print_message(const char *string);
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void XferToRam(void)
+{
+ unsigned int temp;
+ void (*entry_point) (void);
+
+ cons_hook();
+
+ print_message("Copying image from Flash to Ram.\n");
+ for (temp = 0; temp < (0x100000 - 0x20000); temp = temp + 4) {
+ *(volatile unsigned int *) (temp + 0xa0400000) =
+ *(volatile unsigned int *) (temp + srcAddr);
+ if (*(volatile unsigned int *) (temp + 0xa0400000) !=
+ *(volatile unsigned int *) (temp + srcAddr)) {
+ print_message
+ ("Error!: copy verification failed.\n");
+ break;
+ }
+ }
+
+ print_message("Now jumping to the code just xferred to ram.\n");
+ entry_point = (void *) 0x80400000;
+ entry_point();
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static int PortAddress(unsigned int channel, unsigned char reg)
+{
+ unsigned int channelOffset = 0x20;
+ unsigned int regDelta = 4;
+ return (port + (channel * channelOffset) + (reg * regDelta));
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static void cons_hook(void)
+{
+ register int comstat;
+ unsigned temp;
+ unsigned int channel = 1; // Channel 1 is the main serial
+ // connector of the EVB64120A. Channel 0
+ // is the secondary serial port (typically
+ // the unsoldered connector of the board).
+
+ temp = *(unsigned int *) 0xb4000464;
+ *(unsigned int *) 0xb4000464 = 0xffff4f14;
+
+ // Set Baud Rate, baud=115K
+ outb(0x83, PortAddress(channel, UART_LCR));
+ outb(0x00, PortAddress(channel, UART_DLM));
+ outb(0x02, PortAddress(channel, UART_DLL));
+ outb(0x03, PortAddress(channel, UART_LCR));
+
+ comstat = inb(PortAddress(channel, UART_LSR));
+ comstat = inb(PortAddress(channel, UART_RX));
+ outb(0x00, PortAddress(channel, UART_IER));
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+static void print_message(const char *string)
+{
+ register int count, loop;
+ /* Display Opening Message */
+ for (count = 0; string[count]; count++) {
+ if (string[count] == '\n') {
+ *(char *) 0xbd000020 = '\r';
+ }
+ *(char *) 0xbd000020 = string[count];
+ for (loop = 0; loop < 2000; loop++) {
+ }
+ }
+}
diff --git a/arch/mips/galileo-boards/ev64120/dma.c b/arch/mips/galileo-boards/ev64120/dma.c
new file mode 100644
index 000000000..977a2d57c
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/dma.c
@@ -0,0 +1,168 @@
+/* DMA.C - DMA functions and definitions */
+
+/* Copyright Galileo Technology. */
+
+/*
+DESCRIPTION
+This file gives the user a complete interface to the powerful DMA engines,
+including functions for controling the priority mechanism.
+To fully understand the capabilities of the DMA engines please spare some
+time to go trough the spec.
+*/
+
+/* includes */
+
+#ifdef __linux__
+#include <asm/galileo/evb64120A/core.h>
+#include <asm/galileo/evb64120A/dma.h>
+#else
+#include "Core.h"
+#include "DMA.h"
+#endif
+/********************************************************************
+* dmaCommand - Write a command to a DMA channel
+*
+* Inputs: DMA_ENGINE channel - choosing one of the four engine.
+* unsigned int command - The command to be written to the control register.
+* Returns: false if one of the parameters is erroneous else returns true.
+*********************************************************************/
+
+bool dmaCommand(DMA_ENGINE channel, unsigned int command)
+{
+ if (channel > LAST_DMA_ENGINE)
+ return false;
+ GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command);
+ return true;
+}
+
+/********************************************************************
+* dmaTransfer - transfer data from sourceAddr to destAddr on DMA channel
+* Inputs:
+* DMA_RECORED *nextRecoredPointer: If we are using chain mode DMA transfer,
+* then this pointer should point to the next recored,otherwise it should be
+* NULL.
+* VERY IMPORTANT !!! When using chain mode, the records must be 16 Bytes
+* aligned, the function will take care of that for you, but you need to
+* allocate one more record for that, meaning: if you are having 3 records ,
+* declare 4 (see the example bellow) and start using the second one.
+* Example:
+* Performing a chain mode DMA transfer(Copy a 1/4 mega of data using
+* chain mode DMA):
+* DMA_RECORED dmaRecoredArray[4];
+* dmaRecoredArray[1].ByteCnt = _64KB;
+* dmaRecoredArray[1].DestAdd = destAddress + _64KB;
+* dmaRecoredArray[1].SrcAdd = sourceAddress + _64KB;
+* dmaRecoredArray[1].NextRecPtr = &dmaRecoredArray[2];
+* dmaRecoredArray[2].ByteCnt = _64KB;
+* dmaRecoredArray[2].DestAdd = destAddress + 2*_64KB;
+* dmaRecoredArray[2].SrcAdd = sourceAddress + 2*_64KB;
+* dmaRecoredArray[2].NextRecPtr = &dmaRecoredArray[3];
+* dmaRecoredArray[3].ByteCnt = _64KB;
+* dmaRecoredArray[3].DestAdd = destAddress + 3*_64KB;
+* dmaRecoredArray[3].SrcAdd = sourceAddress + 3*_64KB;
+* dmaRecoredArray[3].NextRecPtr = NULL;
+* performCmDma(0,sourceAddress,destAddress,_64KB,PLAIN,WAIT_TO_END,
+* &dmaRecoredArray[1]);
+* Returns: NO_SUCH_CHANNEL if channel does not exist, CHANNEL_BUSY if channel
+* is active and true if the transfer ended successfully
+*********************************************************************/
+
+DMA_STATUS dmaTransfer(DMA_ENGINE channel, unsigned int sourceAddr,
+ unsigned int destAddr, unsigned int numOfBytes,
+ unsigned int command,
+ DMA_RECORED * nextRecoredPointer)
+{
+ unsigned int tempData, checkBits, alignmentOffset = 0;
+ DMA_RECORED *next = nextRecoredPointer;
+
+ if (channel > LAST_DMA_ENGINE)
+ return NO_SUCH_CHANNEL;
+ if (numOfBytes > 0xffff)
+ return GENERAL_ERROR;
+ if (isDmaChannelActive(channel))
+ return CHANNEL_BUSY;
+ if (next != NULL) { /* case of chain Mode */
+ alignmentOffset = ((unsigned int) next % 16);
+ }
+ checkBits = command & 0x6000000;
+ if (checkBits == 0) {
+ while (next != NULL) {
+ WRITE_WORD((unsigned int) next - alignmentOffset,
+ next->ByteCnt);
+ tempData = (unsigned int) next->SrcAdd;
+ WRITE_WORD((unsigned int) next + 4 -
+ alignmentOffset, tempData & 0x5fffffff);
+ tempData = (unsigned int) next->DestAdd;
+ WRITE_WORD((unsigned int) next + 8 -
+ alignmentOffset, tempData & 0x5fffffff);
+ tempData = (unsigned int) next->NextRecPtr;
+ WRITE_WORD((unsigned int) next + 12 -
+ alignmentOffset,
+ tempData & 0x5fffffff -
+ alignmentOffset);
+ next = (DMA_RECORED *) tempData;
+ if (next == nextRecoredPointer)
+ next = NULL;
+ }
+ }
+ GT_REG_WRITE(CHANNEL0_DMA_BYTE_COUNT + channel * 4, numOfBytes);
+ tempData = sourceAddr;
+ GT_REG_WRITE(CHANNEL0_DMA_SOURCE_ADDRESS + channel * 4,
+ tempData & 0x5fffffff);
+ tempData = destAddr;
+ GT_REG_WRITE(CHANNEL0_DMA_DESTINATION_ADDRESS + channel * 4,
+ tempData & 0x5fffffff);
+ if (nextRecoredPointer != NULL) {
+ tempData =
+ (unsigned int) nextRecoredPointer - alignmentOffset;
+ GT_REG_WRITE(CHANNEL0NEXT_RECORD_POINTER + 4 * channel,
+ tempData & 0x5fffffff);
+ command = command | CHANNEL_ENABLE;
+ } else {
+ command = command | CHANNEL_ENABLE | NON_CHAIN_MOD;
+ }
+ /* Activate DMA engine By writting to dmaControlRegister */
+ GT_REG_WRITE(CHANNEL0CONTROL + channel * 4, command);
+
+ return DMA_OK;
+}
+
+/********************************************************************
+* isDmaChannelActive - check if channel is busy
+*
+* Inputs: channel number
+* RETURNS: True if the channel is busy, false otherwise.
+*********************************************************************/
+
+bool isDmaChannelActive(DMA_ENGINE channel)
+{
+ unsigned int data;
+
+ if (channel > LAST_DMA_ENGINE)
+ return false;
+ GT_REG_READ(CHANNEL0CONTROL + 4 * channel, &data);
+ if (data & DMA_ACTIVITY_STATUS)
+ return true;
+ else
+ return false;
+}
+
+
+/********************************************************************
+* changeDmaPriority - update the arbiter`s priority for channels 0-3
+*
+* Inputs: priority for channels 0-1, priority for channels 2-3,
+ priority for groups and other priority options
+* RETURNS: false if one of the parameters is erroneous and true else
+*********************************************************************/
+
+bool changeDmaPriority(PRIO_CHAN_0_1 prio_01, PRIO_CHAN_2_3 prio_23,
+ PRIO_GROUP prioGrp, PRIO_OPT prioOpt)
+{
+ unsigned int prioReg = 0;
+
+ prioReg = (prio_01 & 0x3) + ((prio_23 & 0x3) << 2) +
+ ((prioGrp & 0x3) << 4) + (prioOpt << 6);
+ GT_REG_WRITE(ARBITER_CONTROL, prioReg);
+ return true;
+}
diff --git a/arch/mips/galileo-boards/ev64120/i2o.c b/arch/mips/galileo-boards/ev64120/i2o.c
new file mode 100644
index 000000000..bd2938bf9
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/i2o.c
@@ -0,0 +1,689 @@
+/* i2o.c - Drivers for the I2O */
+
+/* Copyright - Galileo technology. */
+
+/*includes*/
+
+#include <linux/module.h>
+
+#ifdef __linux__
+#include <asm/galileo-boards/evb64120A/core.h>
+#include <asm/galileo-boards/evb64120A/i2o.h>
+#else
+#include "Core.h"
+#include "i2o.h"
+#endif
+
+/********************************************************************
+* getInBoundMessage - When the GT is configured for I2O support
+* it can receive a message from an agent on the pci bus.
+* This message is a 32 bit wide and can be read by
+* the CPU.
+* The messaging unit contains two sets of registers
+* so, actually it can receive a 64 bit message.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: Data received from the remote agent.
+*********************************************************************/
+unsigned int getInBoundMessage(I2O_MESSAGE_REG messageRegNum)
+{
+ unsigned int regValue;
+
+ GT_REG_READ(INBOUND_MESSAGE_REGISTER0_CPU_SIDE + 4 * messageRegNum,
+ &regValue);
+ return (regValue);
+}
+
+
+/********************************************************************
+* checkInboundIntAndClear - When a message is received an interrupt is
+* generated, to enable polling instead the use of
+* an interrupt handler the user can use this fuction.
+* You will need to mask the incomming interrupt for
+* proper use.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+* false.
+*********************************************************************/
+bool checkInBoundIntAndClear(I2O_MESSAGE_REG messageRegNum)
+{
+ unsigned int regValue;
+
+ GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regValue);
+ /* clears bit 0 for message register 0 or bit 1 for message register 1 */
+ GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE,
+ BIT1 * messageRegNum);
+ switch (messageRegNum) {
+ case MESSAGE_REG_0:
+ if (regValue & BIT0)
+ return true;
+ break;
+ case MESSAGE_REG_1:
+ if (regValue & BIT1)
+ return true;
+ break;
+ }
+ return false;
+}
+
+/********************************************************************
+* sendOutBoundMessage - When the GT is configured for I2O support
+* it can send a message to an agent on the pci bus.
+* This message is a 32 bit wide and can be read by
+* the PCI agent.
+* The messaging unit contains two sets of registers
+* so, actually it can send a 64 bit message.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* unsigned int message - Message to be sent.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool sendOutBoundMessage(I2O_MESSAGE_REG messageRegNum,
+ unsigned int message)
+{
+ GT_REG_WRITE(OUTBOUND_MESSAGE_REGISTER0_CPU_SIDE +
+ 4 * messageRegNum, message);
+ return true;
+}
+
+/********************************************************************
+* checkOutboundInt - When the CPU sends a message to the Outbound
+* register it generates an interrupt which is refelcted on
+* the Outbound Interrupt cause register, the interrupt can
+* be cleard only by the PCI agent which read the message.
+* After sending the message you can acknowledge it by
+* monitoring the corresponding bit in the cause register.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+* false.
+*********************************************************************/
+bool outBoundMessageAcknowledge(I2O_MESSAGE_REG messageRegNum)
+{
+ unsigned int regValue;
+
+ GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regValue);
+ switch (messageRegNum) {
+ case MESSAGE_REG_0:
+ if (regValue & BIT0)
+ return true;
+ break;
+ case MESSAGE_REG_1:
+ if (regValue & BIT1)
+ return true;
+ break;
+ }
+ return false;
+}
+
+/********************************************************************
+* maskInBoundMessageInterrupt - Mask the inbound interrupt, when masking
+* the interrupt you can work in polling mode
+* using the checkInboundIntAndClear function.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool maskInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
+{
+ switch (messageRegNum) {
+ case MESSAGE_REG_0:
+ SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ BIT0);
+ break;
+ case MESSAGE_REG_1:
+ SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ BIT1);
+ break;
+ }
+ return true;
+}
+
+/********************************************************************
+* enableInBoundMessageInterrupt - unMask the inbound interrupt.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool enableInBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
+{
+ switch (messageRegNum) {
+ case MESSAGE_REG_0:
+ RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ BIT0);
+ break;
+ case MESSAGE_REG_1:
+ RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ BIT1);
+ break;
+ }
+ return true;
+}
+
+/********************************************************************
+* maskOutboundMessageInterrupt - Mask the out bound interrupt, when doing so
+* the PCI agent needs to poll on the interrupt
+* cause register to monitor an incoming message.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool maskOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
+{
+ switch (messageRegNum) {
+ case MESSAGE_REG_0:
+ SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ BIT0);
+ break;
+ case MESSAGE_REG_1:
+ SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ BIT1);
+ break;
+ }
+ return true;
+}
+
+/********************************************************************
+* enableOutboundMessageInterrupt - Mask the out bound interrupt, when doing so
+* the PCI agent needs to poll on the interrupt
+* cause register to monitor an incoming message.
+*
+* INPUTS: I2O_MESSAGE_REG messageRegNum - Selected set (0 or 1) register.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool enableOutBoundMessageInterrupt(I2O_MESSAGE_REG messageRegNum)
+{
+ switch (messageRegNum) {
+ case MESSAGE_REG_0:
+ RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ BIT0);
+ break;
+ case MESSAGE_REG_1:
+ RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ BIT1);
+ break;
+ }
+ return true;
+}
+
+/********************************************************************
+* initiateOutBoundDoorBellInt - Setting a bit in this register to '1' by the
+* CPU generates a PCI interrupt (if it is not masked by
+* the Outbound interrupt Mask register)
+* Only the PCI agent which recieved the interrupt can
+* clear it, only after clearing all the bits the
+* interrupt will be de-asserted.
+*
+* INPUTS: unsigned int data - Requested interrupt bits.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool initiateOutBoundDoorBellInt(unsigned int data)
+{
+ GT_REG_WRITE(OUTBOUND_DOORBELL_REGISTER_CPU_SIDE, data);
+ return true;
+}
+
+/********************************************************************
+* readInBoundDoorBellInt - Read the in bound door bell interrupt cause
+* register.
+*
+* OUTPUT: N/A.
+* RETURNS: The 32 bit interrupt cause register.
+*********************************************************************/
+unsigned int readInBoundDoorBellInt()
+{
+ unsigned int regData;
+ GT_REG_READ(INBOUND_DOORBELL_REGISTER_CPU_SIDE, &regData);
+ return regData;
+}
+
+/********************************************************************
+* clearInBoundDoorBellInt - An interrupt generated by a PCI agent through
+* the in bound door bell mechanisem can be cleared
+* only by the CPU. The interrupt will be de-asserted
+* only if all the bits which where set by the PCI
+* agent are cleared.
+*
+* INPUTS: unsigned int data - Bits to be cleared.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool clearInBoundDoorBellInt(unsigned int data)
+{
+ GT_REG_WRITE(INBOUND_DOORBELL_REGISTER_CPU_SIDE, data);
+ return true;
+}
+
+/********************************************************************
+* isInBoundDoorBellInterruptSet - Check if Inbound Doorbell Interrupt is set,
+* can be used for polling mode.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+* false.
+*********************************************************************/
+bool isInBoundDoorBellInterruptSet()
+{
+ unsigned int regData;
+
+ GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
+ return (regData & BIT2);
+}
+
+/********************************************************************
+* isOutBoundDoorBellInterruptSet - Check if out bound Doorbell Interrupt is
+* set, can be used for acknowledging interrupt
+* handling by the agent who recieived the
+* interrupt.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+* false.
+*********************************************************************/
+bool isOutBoundDoorBellInterruptSet()
+{
+ unsigned int regData;
+
+ GT_REG_READ(OUTBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
+ return (regData & BIT2);
+}
+
+/********************************************************************
+* maskInboundDoorBellInterrupt - Mask the Inbound Doorbell Interrupt.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool maskInBoundDoorBellInterrupt()
+{
+ SET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
+ return true;
+}
+
+/********************************************************************
+* enableInboundDoorBellInterrupt - unMask the Inbound Doorbell Interrupt.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool enableInBoundDoorBellInterrupt()
+{
+ RESET_REG_BITS(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
+ return true;
+}
+
+/********************************************************************
+* maskOutboundDoorBellInterrupt - Mask the Outbound Doorbell Interrupt.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool maskOutBoundDoorBellInterrupt()
+{
+ SET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
+ return true;
+}
+
+/********************************************************************
+* enableOutboundDoorBellInterrupt - unMask the Outbound Doorbell Interrupt.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool enableOutBoundDoorBellInterrupt()
+{
+ RESET_REG_BITS(OUTBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, BIT2);
+ return true;
+}
+
+/********************************************************************
+* circularQueueEnable - Initialize the I2O messaging mechanism.
+*
+* INPUTS: CIRCULE_QUEUE_SIZE cirQueSize - Bits 5:1 in the:
+* Queue Control Register, Offset 0x50 (0x1c50).
+* Defines the queues size (refer to the data sheet
+* for more information)
+* unsigned int queueBaseAddr - The base address for the first queue.
+* The other queues base Address will be determined as follows:
+* Inbound Free = queueBaseAddr
+* Inbound Post = queueBaseAddr + cirQueSize
+* Outbound Post = queueBaseAddr + cirQueSize
+*
+* OUTPUT: N/A.
+* RETURNS: true.
+*
+* The Circular Queue Starting Addresses as written in the spec:
+* ----------------------------------------
+* | Queue | Starting Address |
+* |----------------|---------------------|
+* | Inbound Free | QBAR |
+* | Inbound Post | QBAR + Queue Size |
+* | Outbound Post | QBAR + 2*Queue Size |
+* | Outbound Free | QBAR + 3*Queue Size |
+* ----------------------------------------
+*********************************************************************/
+bool circularQueueEnable(CIRCULAR_QUEUE_SIZE cirQueSize,
+ unsigned int queueBaseAddr)
+{
+ unsigned int regData;
+
+ regData = BIT0 | (cirQueSize << 1);
+ /* Enable Queue Operation */
+ GT_REG_WRITE(QUEUE_CONTROL_REGISTER_CPU_SIDE, regData);
+ /* Writing The base Address for the 4 Queues */
+ GT_REG_WRITE(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, queueBaseAddr);
+ /* Update The Inbound Free Queue Base Address, offset=0 */
+ GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE, 0);
+ GT_REG_WRITE(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE, 0);
+ /* Update The Inbound Post Queue Base Address, offset=_16K*cirQueSize */
+ GT_REG_WRITE(INBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
+ _16K * cirQueSize);
+ GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
+ _16K * cirQueSize);
+ /* Update The Outbound Post Queue Base Address, offset=2*_16K*cirQueSize */
+ GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
+ 2 * _16K * cirQueSize);
+ GT_REG_WRITE(OUTBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
+ 2 * _16K * cirQueSize);
+ /* Update The Outbound Free Queue Base Address, offset=3*_16K*cirQueSize */
+ GT_REG_WRITE(OUTBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+ 3 * _16K * cirQueSize);
+ GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+ 3 * _16K * cirQueSize);
+ return true;
+}
+
+/********************************************************************
+* inBoundPostQueuePop - Two actions are being taken upon pop:
+* 1) Getting out the data from the Queue`s head.
+* 2) Increment the tail pointer in a cyclic way (The HEAD is
+* incremented automaticaly by the GT)
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: Data pointed by tail.
+*********************************************************************/
+unsigned int inBoundPostQueuePop()
+{
+ unsigned int tailAddrPointer;
+ unsigned int data;
+ unsigned int cirQueSize;
+ unsigned int qBar;
+ unsigned int inBoundPostQbase;
+
+ /* Gets the Inbound Post TAIL pointer */
+ GT_REG_READ(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
+ &tailAddrPointer);
+ /* Gets the Data From the pointer Address */
+ READ_WORD(tailAddrPointer, &data);
+ /* incrementing head process: */
+ /* Gets the fifo's base Address */
+ GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
+ qBar = qBar & 0xfff00000;
+ /* Gets the fifo's size */
+ GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
+ cirQueSize = 0x1f && (cirQueSize >> 1);
+ /* calculating The Inbound Post Queue Base Address */
+ inBoundPostQbase = qBar + 1 * cirQueSize * _16K;
+ /* incrementing Inbound Post queue TAIL in a cyclic loop */
+ tailAddrPointer = inBoundPostQbase + ((tailAddrPointer + 4) %
+ (_16K * cirQueSize));
+ /* updating the pointer back to INBOUND_POST_TAIL_POINTER_REGISTER */
+ GT_REG_WRITE(INBOUND_POST_TAIL_POINTER_REGISTER_CPU_SIDE,
+ tailAddrPointer);
+ return data;
+}
+
+/********************************************************************
+* isInBoundPostQueueInterruptSet - Check if in bound interrupt is set.
+* can be used for polling mode.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true if the corresponding bit in the cause register is set otherwise
+* false.
+*********************************************************************/
+bool isInBoundPostQueueInterruptSet()
+{
+ unsigned int regData;
+
+ GT_REG_READ(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, &regData);
+ return (regData & BIT4); /* if set return '1' (true), else '0' (false) */
+}
+
+/********************************************************************
+* clearInBoundPostQueueInterrupt - Clears the Post queue interrupt.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool clearInBoundPostQueueInterrupt()
+{
+ GT_REG_WRITE(INBOUND_INTERRUPT_CAUSE_REGISTER_CPU_SIDE, BIT4);
+ return true;
+}
+
+/********************************************************************
+* maskInBoundPostQueueInterrupt - Mask the inbound interrupt, when masking
+* the interrupt you can work in polling mode.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS:
+*********************************************************************/
+void maskInBoundPostQueueInterrupt()
+{
+ unsigned int regData;
+
+ GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, &regData);
+ GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ regData | BIT4);
+
+}
+
+/********************************************************************
+* enableInBoundPostQueueInterrupt - Enable interrupt when ever there is a new
+* message from the PCI agent.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS:
+*********************************************************************/
+void enableInBoundPostQueueInterrupt()
+{
+ unsigned int regData;
+
+ GT_REG_READ(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE, &regData);
+ GT_REG_WRITE(INBOUND_INTERRUPT_MASK_REGISTER_CPU_SIDE,
+ regData & 0xfffffffb);
+}
+
+/********************************************************************
+* inBoundFreeQueuePush - Two actions are being taken upon push:
+* 1) Place the user`s data on the Queue`s head.
+* 2) Increment the haed pointer in a cyclic way (The tail is
+* decremented automaticaly by the GT)
+*
+* INPUTS: unsigned int data - Data to be placed in the queue.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool inBoundFreeQueuePush(unsigned int data)
+{
+ unsigned int headPointer;
+ unsigned int cirQueSize;
+ unsigned int qBar;
+ unsigned int inBoundFreeQbase;
+
+ GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+ &headPointer);
+ /* placing the data in the queue */
+ WRITE_WORD(headPointer, data);
+ /* incrementing head process: */
+ /* Gets the fifo's base Address */
+ GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
+ qBar = qBar & 0xfff00000;
+ /* Gets the fifo's size */
+ GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
+ cirQueSize = 0x1f && (cirQueSize >> 1);
+ /* calculating The Inbound Free Queue Base Address */
+ inBoundFreeQbase = qBar;
+ /* incrementing Inbound Free queue HEAD in a cyclic loop */
+ headPointer =
+ inBoundFreeQbase + ((headPointer + 4) % (_16K * cirQueSize));
+ /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */
+ GT_REG_WRITE(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+ headPointer);
+ return true;
+}
+
+/********************************************************************
+* isInBoundFreeQueueEmpty - Check if Inbound Free Queue Empty.
+* Can be used for acknowledging the messages
+* being sent by us to the PCI agent.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true if the queue is empty , otherwise false.
+*********************************************************************/
+bool isInBoundFreeQueueEmpty()
+{
+ unsigned int inBoundFreeQueHead;
+ unsigned int inBoundFreeQueTail;
+
+ GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+ &inBoundFreeQueHead);
+ GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+ &inBoundFreeQueTail);
+ if (inBoundFreeQueHead == inBoundFreeQueTail) {
+ return true;
+ } else
+ return false;
+}
+
+/********************************************************************
+* outBoundPostQueuePush - Two actions are being taken upon push:
+* 1) Place the user`s data on the Queue`s head.
+* 2) Increment the haed pointer in a cyclic way (The tail is
+* decremented automaticaly by the GT when the Agent on the
+* PCI have read data from the Outbound Port).
+*
+* INPUTS: unsigned int data - Data to be placed in the queue`s head.
+* OUTPUT: N/A.
+* RETURNS: true.
+*********************************************************************/
+bool outBoundPostQueuePush(unsigned int data)
+{
+ unsigned int headPointer;
+ unsigned int cirQueSize;
+ unsigned int qBar;
+ unsigned int outBoundPostQbase;
+
+ GT_REG_READ(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
+ &headPointer);
+ /* placing the data in the queue (where the head point to..) */
+ WRITE_WORD(headPointer, data);
+ /* incrementing head process: */
+ /* Gets the fifo's base Address */
+ GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
+ qBar = qBar & 0xfff00000;
+ /* Gets the fifo's size */
+ GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
+ cirQueSize = 0x1f && (cirQueSize >> 1);
+ /* calculating The Outbound Post Queue Base Address */
+ outBoundPostQbase = qBar + 2 * cirQueSize * _16K;
+ /* incrementing Outbound Post queue in a cyclic loop */
+ headPointer =
+ outBoundPostQbase + ((headPointer + 4) % (_16K * cirQueSize));
+ /* updating the pointer back to OUTBOUND_POST_HEAD_POINTER_REGISTER */
+ GT_REG_WRITE(OUTBOUND_POST_HEAD_POINTER_REGISTER_CPU_SIDE,
+ headPointer);
+ return true;
+}
+
+/********************************************************************
+* isOutBoundPostQueueEmpty - Check if Outbound Post Queue Empty.
+* Can be used for acknowledging the messages
+* being sent by us to the PCI agent.
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: true if the queue is empty , otherwise false.
+*********************************************************************/
+bool isOutBoundPostQueueEmpty()
+{
+ unsigned int outBoundPostQueHead;
+ unsigned int outBoundPostQueTail;
+
+ GT_REG_READ(INBOUND_FREE_HEAD_POINTER_REGISTER_CPU_SIDE,
+ &outBoundPostQueHead);
+ GT_REG_READ(INBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+ &outBoundPostQueTail);
+ if (outBoundPostQueHead == outBoundPostQueTail) {
+ return true;
+ } else
+ return false;
+}
+
+/********************************************************************
+* outBoundFreeQueuePop - Two actions are being taken upon pop:
+* 1) Getting out the data from the Queue`s head.
+* 2) Increment the tail pointer in a cyclic way (The HEAD is
+* incremented automaticaly by the GT)
+*
+* INPUTS: N/A.
+* OUTPUT: N/A.
+* RETURNS: Data pointed by tail.
+*********************************************************************/
+unsigned int outBoundFreeQueuePop()
+{
+ unsigned int tailAddrPointer;
+ unsigned int data;
+ unsigned int cirQueSize;
+ unsigned int qBar;
+ unsigned int outBoundFreeQbase;
+
+ /* Gets the Inbound Post TAIL pointer */
+ GT_REG_READ(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+ &tailAddrPointer);
+ /* Gets the Data From the pointer Address */
+ READ_WORD(tailAddrPointer, &data);
+ /* incrementing head process: */
+ /* Gets the fifo's base Address */
+ GT_REG_READ(QUEUE_BASE_ADDRESS_REGISTER_CPU_SIDE, &qBar);
+ qBar = qBar & 0xfff00000;
+ /* Gets the fifo's size */
+ GT_REG_READ(QUEUE_CONTROL_REGISTER_CPU_SIDE, &cirQueSize);
+ cirQueSize = 0x1f && (cirQueSize >> 1);
+ /* calculating The Inbound Post Queue Base Address */
+ outBoundFreeQbase = qBar + 3 * cirQueSize * _16K;
+ /* incrementing Outbound Free queue TAlL in a cyclic loop */
+ tailAddrPointer = outBoundFreeQbase + ((tailAddrPointer + 4) %
+ (_16K * cirQueSize));
+ /* updating the pointer back to OUTBOUND_FREE_TAIL_POINTER_REGISTER */
+ GT_REG_WRITE(OUTBOUND_FREE_TAIL_POINTER_REGISTER_CPU_SIDE,
+ tailAddrPointer);
+ return data;
+}
+
+
+EXPORT_SYMBOL(isInBoundDoorBellInterruptSet);
+EXPORT_SYMBOL(initiateOutBoundDoorBellInt);
+EXPORT_SYMBOL(clearInBoundDoorBellInt);
diff --git a/arch/mips/galileo-boards/ev64120/int-handler.S b/arch/mips/galileo-boards/ev64120/int-handler.S
new file mode 100644
index 000000000..26e96c149
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/int-handler.S
@@ -0,0 +1,117 @@
+/*
+ * int-handler.S
+ *
+ * $Id: int-handler.S,v 1.1 2000/11/21 00:48:25 stevej Exp $
+ * Based on the cobalt handler.
+ *
+ */
+
+#include <linux/config.h>
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+
+/********************************************************************
+ *galileo_handle_int -
+ We check for the timer first, then check PCI ints A and D.
+ Then check for serial IRQ and fall through.
+*********************************************************************/
+ .align 5
+ .set reorder
+ .set noat
+ NESTED(galileo_handle_int, PT_SIZE, sp)
+ SAVE_ALL
+ CLI
+ .set at
+ mfc0 t0,CP0_CAUSE
+ mfc0 t2,CP0_STATUS
+
+ and t0,t2
+
+ andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */
+ bnez t1,ll_galileo_irq
+ andi t1,t0,STATUSF_IP2 /* int0 hardware line */
+ bnez t1,ll_pci_intA
+ andi t1,t0,STATUSF_IP5 /* int3 hardware line */
+ bnez t1,ll_pci_intD
+ andi t1,t0,STATUSF_IP6 /* int4 hardware line */
+ bnez t1,ll_serial_irq
+ andi t1,t0,STATUSF_IP7 /* compare int */
+ bnez t1,ll_compare_irq
+ nop
+
+ /* wrong alarm or masked ... */
+ j spurious_interrupt
+ nop
+ END(galileo_handle_int)
+
+
+ .align 5
+ .set reorder
+ll_galileo_irq:
+ li a0,4
+ move a1,sp
+ jal do_IRQ
+ nop
+ j ret_from_irq
+ nop
+
+ .align 5
+ .set reorder
+ll_compare_irq:
+ li a0,7
+ move a1,sp
+ jal do_IRQ
+ nop
+ j ret_from_irq
+ nop
+
+ .align 5
+ .set reorder
+ll_pci_intA:
+ move a0,sp
+ jal pci_intA
+ nop
+ j ret_from_irq
+ nop
+
+#if 0
+ .align 5
+ .set reorder
+ll_pci_intB:
+ move a0,sp
+ jal pci_intB
+ nop
+ j ret_from_irq
+ nop
+
+ .align 5
+ .set reorder
+ll_pci_intC:
+ move a0,sp
+ jal pci_intC
+ nop
+ j ret_from_irq
+ nop
+#endif
+
+ .align 5
+ .set reorder
+ll_pci_intD:
+ move a0,sp
+ jal pci_intD
+ nop
+ j ret_from_irq
+ nop
+
+ .align 5
+ .set reorder
+ll_serial_irq:
+ li a0,6
+ move a1,sp
+ jal do_IRQ
+ nop
+ j ret_from_irq
+ nop
diff --git a/arch/mips/galileo-boards/ev64120/irq-handler.c b/arch/mips/galileo-boards/ev64120/irq-handler.c
new file mode 100644
index 000000000..a259ea7cd
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/irq-handler.c
@@ -0,0 +1,274 @@
+/*
+ * Galileo Technology chip interrupt handler
+ *
+ * Modified by RidgeRun, Inc.
+ *
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <asm/ptrace.h>
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <asm/galileo-boards/gt64120.h>
+#include <asm/galileo-boards/ev64120.h>
+#include <asm/galileo-boards/ev64120int.h>
+
+/*
+ These are interrupt handlers for the GT on-chip interrupts. They
+ all come in to the MIPS on a single interrupt line, and have to
+ be handled and ack'ed differently than other MIPS interrupts.
+*/
+
+#if CURRENTLY_UNUSED
+
+struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH];
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr);
+
+/********************************************************************
+ *hook_irq_handler
+ *
+ *Hooks IRQ handler to the system. When the system is interrupted
+ *the interrupt service routine is called.
+ *
+ *Inputs :
+ *int_cause - The interrupt cause number. In EVB64120 two parameters
+ * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ *bit_num - Indicates which bit number in the cause register
+ *isr_ptr - Pointer to the interrupt service routine
+ *
+ *Outputs :
+ *
+ *********************************************************************/
+void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr)
+{
+ irq_handlers[int_cause][bit_num].routine = isr_ptr;
+}
+
+
+/********************************************************************
+ *enable_galileo_irq
+ *
+ *Enables the IRQ on Galileo Chip
+ *
+ *Inputs :
+ *int_cause - The interrupt cause number. In EVB64120 two parameters
+ * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ *bit_num - Indicates which bit number in the cause register
+ *
+ *Outputs :
+ *1 if succesful, 0 if failure
+ *********************************************************************/
+int enable_galileo_irq(int int_cause, int bit_num)
+{
+ if (int_cause == INT_CAUSE_MAIN)
+ SET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER, (1 << bit_num));
+ else if (int_cause == INT_CAUSE_HIGH)
+ SET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+ (1 << bit_num));
+ else
+ return 0;
+ return 1;
+}
+
+/********************************************************************
+ *disable_galileo_irq
+ *
+ *Disables the IRQ on Galileo Chip
+ *
+ *Inputs :
+ *int_cause - The interrupt cause number. In EVB64120 two parameters
+ * are declared, INT_CAUSE_MAIN and INT_CAUSE_HIGH.
+ *bit_num - Indicates which bit number in the cause register
+ *
+ *Outputs :
+ *1 if succesful, 0 if failure
+ *********************************************************************/
+int disable_galileo_irq(int int_cause, int bit_num)
+{
+ if (int_cause == INT_CAUSE_MAIN)
+ RESET_REG_BITS(CPU_INTERRUPT_MASK_REGISTER,
+ (1 << bit_num));
+ else if (int_cause == INT_CAUSE_HIGH)
+ RESET_REG_BITS(CPU_HIGH_INTERRUPT_MASK_REGISTER,
+ (1 << bit_num));
+ else
+ return 0;
+ return 1;
+}
+
+#endif /* UNUSED */
+
+/********************************************************************
+ *galileo_irq -
+ *
+ *Interrupt handler for interrupts coming from the Galileo chip.
+ *It could be timer interrupt, built in ethernet ports etc...
+ *
+ *Inputs :
+ *
+ *Outputs :
+ *
+ *********************************************************************/
+static void galileo_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned int irq_src, int_high_src, irq_src_mask,
+ int_high_src_mask;
+ int handled;
+ unsigned int count;
+ static int counter = 0;
+
+ GT_READ(GT_INTRCAUSE_OFS, &irq_src);
+ GT_READ(GT_INTRMASK_OFS, &irq_src_mask);
+ GT_READ(GT_HINTRCAUSE_OFS, &int_high_src);
+ GT_READ(GT_HINTRMASK_OFS, &int_high_src_mask);
+ irq_src = irq_src & irq_src_mask;
+ int_high_src = int_high_src & int_high_src_mask;
+
+ handled = 0;
+
+ /* Execute all interrupt handlers */
+ /* Check for timer interrupt */
+ if (irq_src & 0x00000800) {
+ handled = 1;
+ irq_src &= ~0x00000800;
+ // RESET_REG_BITS (INTERRUPT_CAUSE_REGISTER,BIT8);
+ do_timer(regs);
+ }
+
+ if (irq_src) {
+ printk(KERN_INFO
+ "Other Galileo interrupt received irq_src %x\n",
+ irq_src);
+#if CURRENTLY_UNUSED
+ for (count = 0; count < MAX_CAUSE_REG_WIDTH; count++) {
+ if (irq_src & (1 << count)) {
+ if (irq_handlers[INT_CAUSE_MAIN][count].
+ routine) {
+ queue_task(&irq_handlers
+ [INT_CAUSE_MAIN][count],
+ &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+ handled = 1;
+ }
+ }
+ }
+#endif /* UNUSED */
+ }
+ GT_WRITE(GT_INTRCAUSE_OFS, 0);
+ GT_WRITE(GT_HINTRCAUSE_OFS, 0);
+
+#undef GALILEO_I2O
+#ifdef GALILEO_I2O
+ /*
+ Future I2O support. We currently attach I2O interrupt handlers to the
+ Galileo interrupt (int 4) and handle them in do_IRQ.
+ */
+ if (isInBoundDoorBellInterruptSet()) {
+ printk(KERN_INFO "I2O doorbell interrupt received.\n");
+ handled = 1;
+ }
+
+ if (isInBoundPostQueueInterruptSet()) {
+ printk(KERN_INFO "I2O Queue interrupt received.\n");
+ handled = 1;
+ }
+
+ /*
+ This normally would be outside of the ifdef, but since
+ we're handling I2O outside of this handler, this
+ printk shows up every time we get a valid I2O
+ interrupt. So turn this off for now.
+ */
+ if (handled == 0) {
+ if (counter < 50) {
+ printk("Spurious Galileo interrupt...\n");
+ counter++;
+ }
+ }
+#endif
+}
+
+/********************************************************************
+ *galileo_time_init -
+ *
+ *Initializes timer using galileo's built in timer.
+ *
+ *
+ *Inputs :
+ *irq - number of irq to be used by the timer
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+
+
+#ifdef CONFIG_SYSCLK_100
+#define Sys_clock (100 * 1000000) // 100 MHz
+#endif
+#ifdef CONFIG_SYSCLK_83
+#define Sys_clock (83.333 * 1000000) // 83.333 MHz
+#endif
+#ifdef CONFIG_SYSCLK_75
+#define Sys_clock (75 * 1000000) // 75 MHz
+#endif
+
+/*
+ This will ignore the standard MIPS timer interrupt handler
+ that is passed in as *irq (=irq0 in ../kernel/time.c).
+ We will do our own timer interrupt handling.
+*/
+void galileo_time_init(struct irqaction *irq)
+{
+ extern irq_desc_t irq_desc[NR_IRQS];
+ static struct irqaction timer;
+
+ /* Disable timer first */
+ GT_WRITE(GT_TC_CONTROL_OFS, 0);
+ /* Load timer value for 100 Hz */
+ GT_WRITE(GT_TC3_OFS, Sys_clock / 100);
+
+ /* Create the IRQ structure entry for the timer. Since we're too early
+ in the boot process to use the "request_irq()" call, we'll hard-code
+ the values to the correct interrupt line.
+ */
+ timer.handler = &galileo_irq;
+ timer.flags = SA_SHIRQ;
+ timer.name = "timer";
+ timer.dev_id = NULL;
+ timer.next = NULL;
+ timer.mask = 0;
+ irq_desc[TIMER].action = &timer;
+
+ /* Enable timer ints */
+ GT_WRITE(GT_TC_CONTROL_OFS, 0xc0);
+ /* clear Cause register first */
+ GT_WRITE(GT_INTRCAUSE_OFS, 0x0);
+ /* Unmask timer int */
+ GT_WRITE(GT_INTRMASK_OFS, 0x800);
+ /* Clear High int register */
+ GT_WRITE(GT_HINTRCAUSE_OFS, 0x0);
+ /* Mask All interrupts at High cause interrupt */
+ GT_WRITE(GT_HINTRMASK_OFS, 0x0);
+
+}
+
+void galileo_irq_init(void)
+{
+ int i, j;
+
+#if CURRENTLY_UNUSED
+ /* Reset irq handlers pointers to NULL */
+ for (i = 0; i < MAX_CAUSE_REGS; i++) {
+ for (j = 0; j < MAX_CAUSE_REG_WIDTH; j++) {
+ irq_handlers[i][j].next = NULL;
+ irq_handlers[i][j].sync = 0;
+ irq_handlers[i][j].routine = NULL;
+ irq_handlers[i][j].data = NULL;
+ }
+ }
+#endif
+
+}
diff --git a/arch/mips/galileo-boards/ev64120/irq.c b/arch/mips/galileo-boards/ev64120/irq.c
new file mode 100644
index 000000000..16aef239b
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/irq.c
@@ -0,0 +1,488 @@
+/*
+ * irq.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Code to handle irqs on GT64120A boards
+ * Derived from mips/orion and Cort <cort@fsmlabs.com>
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/malloc.h>
+#include <linux/random.h>
+#include <linux/irq.h>
+#include <asm/bitops.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+#include <asm/galileo-boards/ev64120int.h>
+
+
+#undef IRQ_DEBUG
+
+#ifdef IRQ_DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+
+asmlinkage void do_IRQ(int irq, struct pt_regs *regs);
+
+#define MAX_AGENTS_PER_INT 21 /* Random number */
+unsigned char pci_int_irq[MAX_AGENTS_PER_INT];
+static int max_interrupts = 0;
+
+/* Duplicate interrupt handlers. */
+/********************************************************************
+ *pci_int(A/B/C/D) -
+ *
+ *Calls all the handlers connected to PCI interrupt A/B/C/D
+ *
+ *Inputs :
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+asmlinkage __inline__ void pci_intA(struct pt_regs *regs)
+{
+ unsigned int count = 0;
+ DBG(KERN_INFO "pci_intA, max_interrupts %d\n", max_interrupts);
+ for (count = 0; count < max_interrupts; count++) {
+ do_IRQ(pci_int_irq[count], regs);
+ }
+}
+
+asmlinkage __inline__ void pci_intD(struct pt_regs *regs)
+{
+ unsigned int count = 0;
+ DBG(KERN_INFO "pci_intD, max_interrupts %d\n", max_interrupts);
+ for (count = 0; count < max_interrupts; count++) {
+ do_IRQ(pci_int_irq[count], regs);
+ }
+}
+
+
+/* Function for careful CP0 interrupt mask access */
+static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
+{
+ unsigned long status = read_32bit_cp0_register(CP0_STATUS);
+ DBG(KERN_INFO "modify_cp0_intmask clr %x, set %x\n", clr_mask,
+ set_mask);
+ DBG(KERN_INFO "modify_cp0_intmask status %x\n", status);
+ status &= ~((clr_mask & 0xFF) << 8);
+ status |= (set_mask & 0xFF) << 8;
+ DBG(KERN_INFO "modify_cp0_intmask status %x\n", status);
+ write_32bit_cp0_register(CP0_STATUS, status);
+}
+
+static inline void mask_irq(unsigned int irq_nr)
+{
+ modify_cp0_intmask(irq_nr, 0);
+}
+
+static inline void unmask_irq(unsigned int irq_nr)
+{
+ modify_cp0_intmask(0, irq_nr);
+}
+
+void disable_irq(unsigned int irq_nr)
+{
+ unsigned long flags;
+
+ DBG(KERN_INFO "disable_irq, irq %d\n", irq_nr);
+ save_and_cli(flags);
+ if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2
+ mask_irq(9 << 2);
+ } else {
+ mask_irq(1 << irq_nr);
+ }
+ restore_flags(flags);
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+ unsigned long flags;
+
+ DBG(KERN_INFO "enable_irq, irq %d\n", irq_nr);
+ save_and_cli(flags);
+ if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2
+ DBG(KERN_INFO __FUNCTION__ " pci interrupt %d\n", irq_nr);
+ unmask_irq(9 << 2);
+ } else {
+ DBG(KERN_INFO __FUNCTION__ " interrupt set mask %d\n",
+ 1 << irq_nr);
+ unmask_irq(1 << irq_nr);
+ }
+ restore_flags(flags);
+}
+
+/*
+ * Generic no controller code
+ */
+
+static void no_irq_enable_disable(unsigned int irq)
+{
+}
+static unsigned int no_irq_startup(unsigned int irq)
+{
+ return 0;
+}
+
+#if 0
+static void no_irq_ack(unsigned int irq)
+{
+ printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
+}
+#endif
+
+struct hw_interrupt_type no_irq_type = {
+ typename:"none",
+ startup:no_irq_startup,
+ shutdown:no_irq_enable_disable,
+ enable:no_irq_enable_disable,
+ disable:no_irq_enable_disable,
+ ack:NULL,
+ end:no_irq_enable_disable,
+};
+
+// ack: no_irq_ack, re-enable later -- SKJ
+
+
+/*
+ * Controller mappings for all interrupt sources:
+ */
+irq_desc_t irq_desc[NR_IRQS];
+
+unsigned long spurious_count = 0;
+
+int get_irq_list(char *buf)
+{
+ int i, len = 0, j;
+ struct irqaction *action;
+
+ len += sprintf(buf + len, " ");
+ for (j = 0; j < smp_num_cpus; j++)
+ len += sprintf(buf + len, "CPU%d ", j);
+ *(char *) (buf + len++) = '\n';
+
+ for (i = 0; i < NR_IRQS; i++) {
+ action = irq_desc[i].action;
+ if (!action || !action->handler)
+ continue;
+ len += sprintf(buf + len, "%3d: ", i);
+ len += sprintf(buf + len, "%10u ", kstat_irqs(i));
+ if (irq_desc[i].handler)
+ len +=
+ sprintf(buf + len, " %s ",
+ irq_desc[i].handler->typename);
+ else
+ len += sprintf(buf + len, " None ");
+ len += sprintf(buf + len, " %s", action->name);
+ for (action = action->next; action; action = action->next) {
+ len += sprintf(buf + len, ", %s", action->name);
+ }
+ len += sprintf(buf + len, "\n");
+ }
+ len += sprintf(buf + len, "BAD: %10lu\n", spurious_count);
+ return len;
+}
+
+asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
+{
+ struct irqaction *action;
+ int cpu;
+
+#ifdef IRQ_DEBUG
+ if (irq != TIMER)
+ DBG(KERN_INFO __FUNCTION__ " irq = %d\n", irq);
+ if (irq != TIMER)
+ DBG(KERN_INFO "cause register = %x\n",
+ read_32bit_cp0_register(CP0_CAUSE));
+ if (irq != TIMER)
+ DBG(KERN_INFO "status register = %x\n",
+ read_32bit_cp0_register(CP0_STATUS));
+#endif
+
+ cpu = smp_processor_id();
+ irq_enter(cpu);
+ kstat.irqs[cpu][irq]++;
+
+ if (irq_desc[irq].handler->ack) {
+ irq_desc[irq].handler->ack(irq);
+ }
+
+ disable_irq(irq);
+
+ action = irq_desc[irq].action;
+ if (action && action->handler) {
+#ifdef IRQ_DEBUG
+ if (irq != TIMER)
+ DBG(KERN_INFO
+ "rr: irq %d action %p and handler %p\n", irq,
+ action, action->handler);
+#endif
+ if (!(action->flags & SA_INTERRUPT))
+ __sti();
+ do {
+ action->handler(irq, action->dev_id, regs);
+ action = action->next;
+ } while (action);
+ __cli();
+ if (irq_desc[irq].handler) {
+ if (irq_desc[irq].handler->end)
+ irq_desc[irq].handler->end(irq);
+ else if (irq_desc[irq].handler->enable)
+ irq_desc[irq].handler->enable(irq);
+ }
+ }
+
+ enable_irq(irq);
+ irq_exit(cpu);
+
+ if (softirq_active(cpu) & softirq_mask(cpu))
+ do_softirq();
+
+ /* unmasking and bottom half handling is done magically for us. */
+}
+
+int request_irq(unsigned int irq,
+ void (*handler) (int, void *, struct pt_regs *),
+ unsigned long irqflags, const char *devname, void *dev_id)
+{
+ struct irqaction *old, **p, *action;
+ unsigned long flags;
+
+ DBG(KERN_INFO "rr:dev %s irq %d handler %x\n", devname, irq,
+ handler);
+ if (irq >= NR_IRQS)
+ return -EINVAL;
+
+ action = (struct irqaction *)
+ kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+ if (!action)
+ return -ENOMEM;
+
+ action->handler = handler;
+ action->flags = irqflags;
+ action->mask = 0;
+ action->name = devname;
+ action->dev_id = dev_id;
+ action->next = NULL;
+
+ save_flags(flags);
+ cli();
+
+ p = &irq_desc[irq].action;
+
+ if ((old = *p) != NULL) {
+ /* Can't share interrupts unless both agree to */
+ if (!(old->flags & action->flags & SA_SHIRQ))
+ return -EBUSY;
+ /* add new interrupt at end of irq queue */
+ do {
+ p = &old->next;
+ old = *p;
+ } while (old);
+ }
+ *p = action;
+
+ restore_flags(flags);
+ if (irq >= 8) {
+ DBG(KERN_INFO "request_irq, max_interrupts %d\n",
+ max_interrupts);
+ pci_int_irq[max_interrupts++] = irq; // NOTE: Add error-handling if > max
+ }
+ enable_irq(irq);
+ return 0;
+}
+
+
+void free_irq(unsigned int irq, void *dev_id)
+{
+ struct irqaction *p, *old = NULL;
+ unsigned long flags;
+ int count, tmp, removed = 0;
+
+ for (p = irq_desc[irq].action; p != NULL; old = p, p = p->next) {
+ /* Found the IRQ, is it the correct dev_id? */
+ if (dev_id == p->dev_id) {
+ save_flags(flags);
+ cli();
+
+ // remove link from list
+ if (old)
+ old->next = p->next;
+ else
+ irq_desc[irq].action = p->next;
+
+ restore_flags(flags);
+ kfree(p);
+ removed = 1;
+ break;
+ }
+ }
+
+ /*
+ Remove PCI interrupts from the pci_int_irq list. Make sure
+ that some handler was removed before decrementing max_interrupts.
+ */
+ if ((irq >= 8) && (removed)) {
+ for (count = 0; count < max_interrupts; count++) {
+ if (pci_int_irq[count] == irq) {
+ for (tmp = count; tmp < max_interrupts;
+ tmp++) {
+ pci_int_irq[tmp] =
+ pci_int_irq[tmp + 1];
+ }
+ }
+ }
+ max_interrupts--;
+ DBG(KERN_INFO "free_irq, max_interrupts %d\n",
+ max_interrupts);
+ }
+}
+
+unsigned long probe_irq_on(void)
+{
+ printk(KERN_INFO "probe_irq_on\n");
+ return 0;
+}
+
+int probe_irq_off(unsigned long irqs)
+{
+ printk(KERN_INFO "probe_irq_off\n");
+ return 0;
+}
+
+int (*irq_cannonicalize) (int irq);
+
+int galileo_irq_cannonicalize(int i)
+{
+ return i;
+}
+
+/********************************************************************
+ *galileo_irq_setup -
+ *
+ *Initializes CPU interrupts
+ *
+ *
+ *Inputs :
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+void galileo_irq_setup(void)
+{
+ extern asmlinkage void galileo_handle_int(void);
+ extern void galileo_irq_init(void);
+
+ DBG(KERN_INFO "rr: galileo_irq_setup entry\n");
+
+ galileo_irq_init();
+
+ /*
+ * Clear all of the interrupts while we change the able around a bit.
+ */
+ set_cp0_status(ST0_IM, 0);
+ set_cp0_status(ST0_BEV, 1); /* int-handler is not on bootstrap */
+
+ /* Sets the exception_handler array. */
+ set_except_vector(0, galileo_handle_int);
+
+ cli();
+
+/*
+ Enable timer. Other interrupts will be enabled as they are registered.
+*/
+ set_cp0_status(ST0_IM, IE_IRQ2);
+
+
+#ifdef CONFIG_REMOTE_DEBUG
+ {
+ extern int DEBUG_CHANNEL;
+ serial_init(DEBUG_CHANNEL);
+ serial_set(DEBUG_CHANNEL, 115200);
+ set_debug_traps();
+ breakpoint(); /* you may move this line to whereever you want :-) */
+ }
+#endif
+
+}
+
+
+void __init init_IRQ(void)
+{
+ int i;
+
+ DBG(KERN_INFO "rr:init_IRQ\n");
+
+ /* Let's initialize our IRQ descriptors */
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_desc[i].status = 0;
+ irq_desc[i].handler = &no_irq_type;
+ irq_desc[i].action = NULL;
+ irq_desc[i].depth = 0;
+ irq_desc[i].lock = SPIN_LOCK_UNLOCKED;
+ }
+
+ irq_cannonicalize = galileo_irq_cannonicalize;
+ galileo_irq_setup();
+}
+
+/* EXPORT_SYMBOL(irq_cannonicalize); */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff --git a/arch/mips/galileo-boards/ev64120/ld.script.galileo b/arch/mips/galileo-boards/ev64120/ld.script.galileo
new file mode 100644
index 000000000..1c9faa3f3
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/ld.script.galileo
@@ -0,0 +1,113 @@
+OUTPUT_FORMAT("elf32-bigmips")
+OUTPUT_ARCH(mips)
+ENTRY(kernel_entry)
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x80100000;
+ /* app_header is needed for the Orion bootloader -- Cort */
+ .app_header : { *(.app_header) }
+ .init : { *(.init) } =0
+ .text :
+ {
+ _ftext = . ;
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+
+ . = ALIGN(8192);
+ .data.init_task : { *(.data.init_task) }
+
+ /* Startup code */
+ . = ALIGN(4096);
+ __init_begin = .;
+ .text.init : { *(.text.init) }
+ .data.init : { *(.data.init) }
+ . = ALIGN(16);
+ __setup_start = .;
+ .setup.init : { *(.setup.init) }
+ __setup_end = .;
+ __initcall_start = .;
+ .initcall.init : { *(.initcall.init) }
+ __initcall_end = .;
+ . = ALIGN(4096); /* Align double page for init_task_union */
+ __init_end = .;
+
+ . = ALIGN(4096);
+ .data.page_aligned : { *(.data.idt) }
+
+ . = ALIGN(32);
+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+ .fini : { *(.fini) } =0
+ .reginfo : { *(.reginfo) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. It would
+ be more correct to do this:
+ . = .;
+ The current expression does not correctly handle the case of a
+ text segment ending precisely at the end of a page; it causes the
+ data segment to skip a page. The above expression does not have
+ this problem, but it will currently (2/95) cause BFD to allocate
+ a single segment, combining both text and data, for this case.
+ This will prevent the text segment from being shared among
+ multiple executions of the program; I think that is more
+ important than losing a page of the virtual address space (note
+ that no actual memory is lost; the page which is skipped can not
+ be referenced). */
+ . = .;
+ .data :
+ {
+ _fdata = . ;
+ *(.data)
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ _gp = . + 0x8000;
+ .lit8 : { *(.lit8) }
+ .lit4 : { *(.lit4) }
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+
+ __bss_start = .;
+ _fbss = .;
+ .sbss : { *(.sbss) *(.scommon) }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ _end = . ;
+ PROVIDE (end = .);
+ }
+ /* These are needed for ELF backends which have not yet been
+ converted to the new style linker. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* DWARF debug sections.
+ Symbols in the .debug DWARF section are relative to the beginning of the
+ section so we begin .debug at 0. It's not clear yet what needs to happen
+ for the others. */
+ .debug 0 : { *(.debug) }
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ .line 0 : { *(.line) }
+ /* These must appear regardless of . */
+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
+}
diff --git a/arch/mips/galileo-boards/ev64120/pci_bios.c b/arch/mips/galileo-boards/ev64120/pci_bios.c
new file mode 100644
index 000000000..96a85a0e0
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/pci_bios.c
@@ -0,0 +1,1266 @@
+/*
+ * pci_bios.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Galileo Evaluation Boards PCI support.
+ *
+ * The general-purpose functions to read/write and configure the GT64120A's
+ * PCI registers (function names start with pci0 or pci1) are either direct
+ * copies of functions written by Galileo Technology, or are modifications
+ * of their functions to work with Linux 2.4 vs Linux 2.2. These functions
+ * are Copyright - Galileo Technology.
+ *
+ * Other functions are derived from other MIPS PCI implementations, or were
+ * written by RidgeRun, Inc, Copyright (C) 2000 RidgeRun, Inc.
+ * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/version.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <asm/galileo-boards/ev64120.h>
+#include <asm/galileo-boards/gt64120.h>
+
+#include <linux/init.h>
+
+#undef PCI_DEBUG
+
+#ifdef PCI_DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+#ifdef CONFIG_PCI
+
+#define SELF 0
+
+/*
+ These functions and structures provide the BIOS scan and mapping of the PCI devices.
+*/
+
+#define MAX_PCI_DEVS 10
+
+struct pci_device {
+ u32 slot;
+ u32 BARtype[6];
+ u32 BARsize[6];
+};
+
+static void __init scan_and_initialize_pci(void);
+static u32 __init scan_pci_bus(struct pci_device *pci_devices);
+static void __init allocate_pci_space(struct pci_device *pci_devices);
+
+static void __init galileo_pcibios_fixup_bus(struct pci_bus *bus);
+
+/*
+ The functions that actually read and write to the controller.
+
+ Copied from or modified from Galileo Technology code.
+*/
+static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device);
+static void pci0WriteConfigReg(unsigned int offset,
+ struct pci_dev *device, unsigned int data);
+static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device);
+static void pci1WriteConfigReg(unsigned int offset,
+ struct pci_dev *device, unsigned int data);
+
+static void pci0MapIOspace(unsigned int pci0IoBase,
+ unsigned int pci0IoLength);
+static void pci1MapIOspace(unsigned int pci1IoBase,
+ unsigned int pci1IoLength);
+static void pci0MapMemory0space(unsigned int pci0Mem0Base,
+ unsigned int pci0Mem0Length);
+static void pci1MapMemory0space(unsigned int pci1Mem0Base,
+ unsigned int pci1Mem0Length);
+static void pci0MapMemory1space(unsigned int pci0Mem1Base,
+ unsigned int pci0Mem1Length);
+static void pci1MapMemory1space(unsigned int pci1Mem1Base,
+ unsigned int pci1Mem1Length);
+static unsigned int pci0GetIOspaceBase(void);
+static unsigned int pci0GetIOspaceSize(void);
+static unsigned int pci0GetMemory0Base(void);
+static unsigned int pci0GetMemory0Size(void);
+static unsigned int pci0GetMemory1Base(void);
+static unsigned int pci0GetMemory1Size(void);
+static unsigned int pci1GetIOspaceBase(void);
+static unsigned int pci1GetIOspaceSize(void);
+static unsigned int pci1GetMemory0Base(void);
+static unsigned int pci1GetMemory0Size(void);
+static unsigned int pci1GetMemory1Base(void);
+static unsigned int pci1GetMemory1Size(void);
+
+
+/* Functions to implement "pci ops" */
+static int galileo_pcibios_read_config_word(struct pci_dev *dev,
+ int offset, u16 * val);
+static int galileo_pcibios_read_config_byte(struct pci_dev *dev,
+ int offset, u8 * val);
+static int galileo_pcibios_read_config_dword(struct pci_dev *dev,
+ int offset, u32 * val);
+static int galileo_pcibios_write_config_byte(struct pci_dev *dev,
+ int offset, u8 val);
+static int galileo_pcibios_write_config_word(struct pci_dev *dev,
+ int offset, u16 val);
+static int galileo_pcibios_write_config_dword(struct pci_dev *dev,
+ int offset, u32 val);
+static void galileo_pcibios_set_master(struct pci_dev *dev);
+
+/*
+ General-purpose PCI functions.
+*/
+
+/********************************************************************
+* pci0MapIOspace - Maps PCI0 IO space for the master.
+* Inputs: base and length of pci0Io
+*********************************************************************/
+
+static void pci0MapIOspace(unsigned int pci0IoBase,
+ unsigned int pci0IoLength)
+{
+ unsigned int pci0IoTop =
+ (unsigned int) (pci0IoBase + pci0IoLength);
+
+ if (pci0IoLength == 0)
+ pci0IoTop++;
+
+ pci0IoBase = (unsigned int) (pci0IoBase >> 21);
+ pci0IoTop = (unsigned int) (((pci0IoTop - 1) & 0x0fffffff) >> 21);
+ GT_WRITE(GT_PCI0IOLD_OFS, pci0IoBase);
+ GT_WRITE(GT_PCI0IOHD_OFS, pci0IoTop);
+}
+
+/********************************************************************
+* pci1MapIOspace - Maps PCI1 IO space for the master.
+* Inputs: base and length of pci1Io
+*********************************************************************/
+
+static void pci1MapIOspace(unsigned int pci1IoBase,
+ unsigned int pci1IoLength)
+{
+ unsigned int pci1IoTop =
+ (unsigned int) (pci1IoBase + pci1IoLength);
+
+ if (pci1IoLength == 0)
+ pci1IoTop++;
+
+ pci1IoBase = (unsigned int) (pci1IoBase >> 21);
+ pci1IoTop = (unsigned int) (((pci1IoTop - 1) & 0x0fffffff) >> 21);
+ GT_WRITE(GT_PCI1IOLD_OFS, pci1IoBase);
+ GT_WRITE(GT_PCI1IOHD_OFS, pci1IoTop);
+}
+
+/********************************************************************
+* pci0MapMemory0space - Maps PCI0 memory0 space for the master.
+* Inputs: base and length of pci0Mem0
+*********************************************************************/
+
+static void pci0MapMemory0space(unsigned int pci0Mem0Base,
+ unsigned int pci0Mem0Length)
+{
+ unsigned int pci0Mem0Top = pci0Mem0Base + pci0Mem0Length;
+
+ if (pci0Mem0Length == 0)
+ pci0Mem0Top++;
+
+ pci0Mem0Base = pci0Mem0Base >> 21;
+ pci0Mem0Top = ((pci0Mem0Top - 1) & 0x0fffffff) >> 21;
+ GT_WRITE(GT_PCI0M0LD_OFS, pci0Mem0Base);
+ GT_WRITE(GT_PCI0M0HD_OFS, pci0Mem0Top);
+}
+
+/********************************************************************
+* pci1MapMemory0space - Maps PCI1 memory0 space for the master.
+* Inputs: base and length of pci1Mem0
+*********************************************************************/
+
+static void pci1MapMemory0space(unsigned int pci1Mem0Base,
+ unsigned int pci1Mem0Length)
+{
+ unsigned int pci1Mem0Top = pci1Mem0Base + pci1Mem0Length;
+
+ if (pci1Mem0Length == 0)
+ pci1Mem0Top++;
+
+ pci1Mem0Base = pci1Mem0Base >> 21;
+ pci1Mem0Top = ((pci1Mem0Top - 1) & 0x0fffffff) >> 21;
+ GT_WRITE(GT_PCI1M0LD_OFS, pci1Mem0Base);
+ GT_WRITE(GT_PCI1M0HD_OFS, pci1Mem0Top);
+}
+
+/********************************************************************
+* pci0MapMemory1space - Maps PCI0 memory1 space for the master.
+* Inputs: base and length of pci0Mem1
+*********************************************************************/
+
+static void pci0MapMemory1space(unsigned int pci0Mem1Base,
+ unsigned int pci0Mem1Length)
+{
+ unsigned int pci0Mem1Top = pci0Mem1Base + pci0Mem1Length;
+
+ if (pci0Mem1Length == 0)
+ pci0Mem1Top++;
+
+ pci0Mem1Base = pci0Mem1Base >> 21;
+ pci0Mem1Top = ((pci0Mem1Top - 1) & 0x0fffffff) >> 21;
+ GT_WRITE(GT_PCI0M1LD_OFS, pci0Mem1Base);
+ GT_WRITE(GT_PCI0M1HD_OFS, pci0Mem1Top);
+
+}
+
+/********************************************************************
+* pci1MapMemory1space - Maps PCI1 memory1 space for the master.
+* Inputs: base and length of pci1Mem1
+*********************************************************************/
+
+static void pci1MapMemory1space(unsigned int pci1Mem1Base,
+ unsigned int pci1Mem1Length)
+{
+ unsigned int pci1Mem1Top = pci1Mem1Base + pci1Mem1Length;
+
+ if (pci1Mem1Length == 0)
+ pci1Mem1Top++;
+
+ pci1Mem1Base = pci1Mem1Base >> 21;
+ pci1Mem1Top = ((pci1Mem1Top - 1) & 0x0fffffff) >> 21;
+ GT_WRITE(GT_PCI1M1LD_OFS, pci1Mem1Base);
+ GT_WRITE(GT_PCI1M1HD_OFS, pci1Mem1Top);
+}
+
+/********************************************************************
+* pci0GetIOspaceBase - Return PCI0 IO Base Address.
+* Inputs: N/A
+* Returns: PCI0 IO Base Address.
+*********************************************************************/
+
+static unsigned int pci0GetIOspaceBase(void)
+{
+ unsigned int base;
+ GT_READ(GT_PCI0IOLD_OFS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci0GetIOspaceSize - Return PCI0 IO Bar Size.
+* Inputs: N/A
+* Returns: PCI0 IO Bar Size.
+*********************************************************************/
+
+static unsigned int pci0GetIOspaceSize(void)
+{
+ unsigned int top, base, size;
+ GT_READ(GT_PCI0IOLD_OFS, &base);
+ base = base << 21;
+ GT_READ(GT_PCI0IOHD_OFS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci0GetMemory0Base - Return PCI0 Memory 0 Base Address.
+* Inputs: N/A
+* Returns: PCI0 Memory 0 Base Address.
+*********************************************************************/
+
+static unsigned int pci0GetMemory0Base(void)
+{
+ unsigned int base;
+ GT_READ(GT_PCI0M0LD_OFS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci0GetMemory0Size - Return PCI0 Memory 0 Bar Size.
+* Inputs: N/A
+* Returns: PCI0 Memory 0 Bar Size.
+*********************************************************************/
+
+static unsigned int pci0GetMemory0Size(void)
+{
+ unsigned int top, base, size;
+ GT_READ(GT_PCI0M0LD_OFS, &base);
+ base = base << 21;
+ GT_READ(GT_PCI0M0HD_OFS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci0GetMemory1Base - Return PCI0 Memory 1 Base Address.
+* Inputs: N/A
+* Returns: PCI0 Memory 1 Base Address.
+*********************************************************************/
+
+static unsigned int pci0GetMemory1Base(void)
+{
+ unsigned int base;
+ GT_READ(GT_PCI0M1LD_OFS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci0GetMemory1Size - Return PCI0 Memory 1 Bar Size.
+* Inputs: N/A
+* Returns: PCI0 Memory 1 Bar Size.
+*********************************************************************/
+
+static unsigned int pci0GetMemory1Size(void)
+{
+ unsigned int top, base, size;
+ GT_READ(GT_PCI0M1LD_OFS, &base);
+ base = base << 21;
+ GT_READ(GT_PCI0M1HD_OFS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci1GetIOspaceBase - Return PCI1 IO Base Address.
+* Inputs: N/A
+* Returns: PCI1 IO Base Address.
+*********************************************************************/
+
+static unsigned int pci1GetIOspaceBase(void)
+{
+ unsigned int base;
+ GT_READ(GT_PCI1IOLD_OFS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci1GetIOspaceSize - Return PCI1 IO Bar Size.
+* Inputs: N/A
+* Returns: PCI1 IO Bar Size.
+*********************************************************************/
+
+static unsigned int pci1GetIOspaceSize(void)
+{
+ unsigned int top, base, size;
+ GT_READ(GT_PCI1IOLD_OFS, &base);
+ base = base << 21;
+ GT_READ(GT_PCI1IOHD_OFS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci1GetMemory0Base - Return PCI1 Memory 0 Base Address.
+* Inputs: N/A
+* Returns: PCI1 Memory 0 Base Address.
+*********************************************************************/
+
+static unsigned int pci1GetMemory0Base(void)
+{
+ unsigned int base;
+ GT_READ(GT_PCI1M0LD_OFS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci1GetMemory0Size - Return PCI1 Memory 0 Bar Size.
+* Inputs: N/A
+* Returns: PCI1 Memory 0 Bar Size.
+*********************************************************************/
+
+static unsigned int pci1GetMemory0Size(void)
+{
+ unsigned int top, base, size;
+ GT_READ(GT_PCI1M1LD_OFS, &base);
+ base = base << 21;
+ GT_READ(GT_PCI1M1HD_OFS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+/********************************************************************
+* pci1GetMemory1Base - Return PCI1 Memory 1 Base Address.
+* Inputs: N/A
+* Returns: PCI1 Memory 1 Base Address.
+*********************************************************************/
+
+static unsigned int pci1GetMemory1Base(void)
+{
+ unsigned int base;
+ GT_READ(GT_PCI1M1LD_OFS, &base);
+ base = base << 21;
+ return base;
+}
+
+/********************************************************************
+* pci1GetMemory1Size - Return PCI1 Memory 1 Bar Size.
+* Inputs: N/A
+* Returns: PCI1 Memory 1 Bar Size.
+*********************************************************************/
+
+static unsigned int pci1GetMemory1Size(void)
+{
+ unsigned int top, base, size;
+ GT_READ(GT_PCI1M1LD_OFS, &base);
+ base = base << 21;
+ GT_READ(GT_PCI1M1HD_OFS, &top);
+ top = (top << 21);
+ size = ((top - base) & 0xfffffff);
+ size = size | 0x1fffff;
+ return (size + 1);
+}
+
+
+
+/********************************************************************
+ *pci_range_ck -
+ *
+ *Check if the pci device that are trying to access does really exists
+ *on the evaluation board.
+ *
+ *Inputs :
+ *bus - bus number (0 for PCI 0 ; 1 for PCI 1)
+ *dev - number of device on the specific pci bus
+ *
+ *Outpus :
+ *0 - if OK , 1 - if failure
+ *********************************************************************/
+static __inline__ int pci_range_ck(unsigned char bus, unsigned char dev)
+{
+ //DBG(KERN_INFO "p_r_c %d %d\n",bus,dev);
+ if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8))
+ return 0; // Bus/Device Number OK
+ return -1; // Bus/Device Number not OK
+}
+
+/********************************************************************
+* pciXReadConfigReg - Read from a PCI configuration register
+* - Make sure the GT is configured as a master before
+* reading from another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+* INPUTS: regOffset: The register offset as it apears in the GT spec (or PCI
+* spec)
+* pciDevNum: The device number needs to be addressed.
+* RETURNS: data , if the data == 0xffffffff check the master abort bit in the
+* cause register to make sure the data is valid
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+static unsigned int pci0ReadConfigReg(int offset, struct pci_dev *device)
+{
+ unsigned int DataForRegCf8;
+ unsigned int data;
+
+ DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+ (PCI_FUNC(device->devfn) << 8) |
+ (offset & ~0x3)) | 0x80000000;
+ GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+
+ /* The casual observer might wonder why the READ is duplicated here,
+ rather than immediately following the WRITE, and just have the
+ swap in the "if". That's because there is a latency problem
+ with trying to read immediately after setting up the address
+ register. The "if" check gives enough time for the address
+ to stabilize, so the READ can work.
+ */
+ if (PCI_SLOT(device->devfn) == SELF) { /* This board */
+ GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+ return data;
+ } else { /* The PCI is working in LE Mode so swap the Data. */
+ GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+ return cpu_to_le32(data);
+ }
+}
+
+static unsigned int pci1ReadConfigReg(int offset, struct pci_dev *device)
+{
+ unsigned int DataForRegCf8;
+ unsigned int data;
+
+ DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+ (PCI_FUNC(device->devfn) << 8) |
+ (offset & ~0x3)) | 0x80000000;
+ /* The casual observer might wonder why the READ is duplicated here,
+ rather than immediately following the WRITE, and just have the
+ swap in the "if". That's because there is a latency problem
+ with trying to read immediately after setting up the address
+ register. The "if" check gives enough time for the address
+ to stabilize, so the READ can work.
+ */
+ if (PCI_SLOT(device->devfn) == SELF) { /* This board */
+ /* when configurating our own PCI 1 L-unit the access is through
+ the PCI 0 interface with reg number = reg number + 0x80 */
+ DataForRegCf8 |= 0x80;
+ GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+ } else { /* The PCI is working in LE Mode so swap the Data. */
+ GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);
+ }
+ if (PCI_SLOT(device->devfn) == SELF) { /* This board */
+ GT_READ(GT_PCI0_CFGDATA_OFS, &data);
+ return data;
+ } else {
+ GT_READ(GT_PCI1_CFGDATA_OFS, &data);
+ return cpu_to_le32(data);
+ }
+}
+
+
+
+/********************************************************************
+* pciXWriteConfigReg - Write to a PCI configuration register
+* - Make sure the GT is configured as a master before
+* writingto another device on the PCI.
+* - The function takes care of Big/Little endian conversion.
+* Inputs: unsigned int regOffset: The register offset as it apears in the GT spec
+* (or any other PCI device spec)
+* pciDevNum: The device number needs to be addressed.
+*
+* Configuration Address 0xCF8:
+*
+* 31 30 24 23 16 15 11 10 8 7 2 0 <=bit Number
+* |congif|Reserved| Bus |Device|Function|Register|00|
+* |Enable| |Number|Number| Number | Number | | <=field Name
+*
+*********************************************************************/
+static void pci0WriteConfigReg(unsigned int offset,
+ struct pci_dev *device, unsigned int data)
+{
+ unsigned int DataForRegCf8;
+
+ DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+ (PCI_FUNC(device->devfn) << 8) |
+ (offset & ~0x3)) | 0x80000000;
+ GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+ if (PCI_SLOT(device->devfn) == SELF) { /* This board */
+ GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+ } else { /* configuration Transaction over the pci. */
+ /* The PCI is working in LE Mode so swap the Data. */
+ GT_WRITE(GT_PCI0_CFGDATA_OFS, le32_to_cpu(data));
+ }
+}
+
+static void pci1WriteConfigReg(unsigned int offset,
+ struct pci_dev *device, unsigned int data)
+{
+ unsigned int DataForRegCf8;
+
+ DataForRegCf8 = ((PCI_SLOT(device->devfn) << 11) |
+ (PCI_FUNC(device->devfn) << 8) |
+ (offset & ~0x3)) | 0x80000000;
+ /* There is a latency problem
+ with trying to read immediately after setting up the address
+ register. The "if" check gives enough time for the address
+ to stabilize, so the WRITE can work.
+ */
+ if (PCI_SLOT(device->devfn) == SELF) { /* This board */
+ /* when configurating our own PCI 1 L-unit the access is through
+ the PCI 0 interface with reg number = reg number + 0x80 */
+ DataForRegCf8 |= 0x80;
+ GT_WRITE(GT_PCI0_CFGADDR_OFS, DataForRegCf8);
+ } else { /* configuration Transaction over the pci. */
+ /* The PCI is working in LE Mode so swap the Data. */
+ GT_WRITE(GT_PCI1_CFGADDR_OFS, DataForRegCf8);
+ }
+ if (PCI_SLOT(device->devfn) == SELF) { /* This board */
+ GT_WRITE(GT_PCI0_CFGDATA_OFS, data);
+ } else { /* configuration Transaction over the pci. */
+ GT_WRITE(GT_PCI1_CFGADDR_OFS, le32_to_cpu(data));
+ }
+}
+
+
+/********************************************************************
+ *galileo_pcibios_(read/write)_config_(dword/word/byte) -
+ *
+ *reads/write a dword/word/byte register from the configuration space
+ *of a device.
+ *
+ *Inputs :
+ *bus - bus number
+ *dev - device number
+ *offset - register offset in the configuration space
+ *val - value to be written / read
+ *
+ *Outputs :
+ *PCIBIOS_SUCCESSFUL when operation was succesfull
+ *PCIBIOS_DEVICE_NOT_FOUND when the bus or dev is errorneous
+ *PCIBIOS_BAD_REGISTER_NUMBER when accessing non aligned
+ *********************************************************************/
+
+static int galileo_pcibios_read_config_dword(struct pci_dev *device,
+ int offset, u32 * val)
+{
+ int dev, bus;
+ //DBG(KERN_INFO "rcd entry \n",offset,val);
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+
+ if (pci_range_ck(bus, dev)) {
+ *val = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ if (offset & 0x3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ if (bus == 0)
+ *val = pci0ReadConfigReg(offset, device);
+// if (bus == 1) *val = pci1ReadConfigReg (offset,device);
+ DBG(KERN_INFO "rr: rcd dev %d offset %x %x\n", dev, offset, *val);
+
+ /* This is so that the upper PCI layer will get the correct return value if
+ we're not attached to anything. */
+ if ((offset == 0) && (*val == 0xffffffff)) {
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_read_config_word(struct pci_dev *device,
+ int offset, u16 * val)
+{
+ int dev, bus;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+
+ if (pci_range_ck(bus, dev)) {
+ *val = 0xffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ if (offset & 0x1)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ if (bus == 0)
+ *val =
+ (unsigned short) (pci0ReadConfigReg(offset, device) >>
+ ((offset & ~0x3) * 8));
+// if (bus == 1) *val = (unsigned short) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8));
+
+ DBG(KERN_INFO "rr: rcw dev %d offset %x %x\n", dev, offset, *val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_read_config_byte(struct pci_dev *device,
+ int offset, u8 * val)
+{
+ int dev, bus;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+
+ if (pci_range_ck(bus, dev)) {
+ *val = 0xff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ if (bus == 0)
+ *val =
+ (unsigned char) (pci0ReadConfigReg(offset, device) >>
+ ((offset & ~0x3) * 8));
+// if (bus == 1) *val = (unsigned char) (pci1ReadConfigReg(offset,device) >> ((offset & ~0x3) * 8));
+
+ DBG(KERN_INFO "rr: rcb dev %d offset %x %x\n", dev, offset, *val);
+
+ /* This is so that the upper PCI layer will get the correct return value if
+ we're not attached to anything. */
+ if ((offset == 0xe) && (*val == 0xff)) {
+ u32 MasterAbort;
+ GT_READ(GT_INTRCAUSE_OFS, &MasterAbort);
+ if (MasterAbort & 0x40000) {
+ DBG(KERN_INFO "PCI Master Abort, ICR %x\n",
+ MasterAbort);
+ GT_WRITE(GT_INTRCAUSE_OFS,
+ (MasterAbort & 0xfffbffff));
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_dword(struct pci_dev *device,
+ int offset, u32 val)
+{
+ int dev, bus;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+
+ if (pci_range_ck(bus, dev))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (offset & 0x3)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ if (bus == 0)
+ pci0WriteConfigReg(offset, device, val);
+// if (bus == 1) pci1WriteConfigReg (offset,device,val);
+
+ DBG(KERN_INFO "rr: wcd dev %d, offset %x, val %x\n", dev, offset,
+ val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int galileo_pcibios_write_config_word(struct pci_dev *device,
+ int offset, u16 val)
+{
+ int dev, bus;
+ unsigned long tmp;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+
+ if (pci_range_ck(bus, dev))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (offset & 0x1)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ if (bus == 0)
+ tmp = pci0ReadConfigReg(offset, device);
+// if (bus == 1) tmp = pci1ReadConfigReg (offset,device);
+
+ if ((offset % 4) == 0)
+ tmp = (tmp & 0xffff0000) | (val & 0xffff);
+ if ((offset % 4) == 2)
+ tmp = (tmp & 0x0000ffff) | ((val & 0xffff) << 16);
+
+ if (bus == 0)
+ pci0WriteConfigReg(offset, device, tmp);
+// if (bus == 1) pci1WriteConfigReg (offset,device,tmp);
+ DBG(KERN_INFO "rr: wcw dev %d, offset %x, val %x\n", dev, offset,
+ val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int galileo_pcibios_write_config_byte(struct pci_dev *device,
+ int offset, u8 val)
+{
+ int dev, bus;
+ unsigned long tmp;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+
+ if (pci_range_ck(bus, dev))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (bus == 0)
+ tmp = pci0ReadConfigReg(offset, device);
+// if (bus == 1) tmp = pci1ReadConfigReg (offset,device);
+
+ if ((offset % 4) == 0)
+ tmp = (tmp & 0xffffff00) | (val & 0xff);
+ if ((offset % 4) == 1)
+ tmp = (tmp & 0xffff00ff) | ((val & 0xff) << 8);
+ if ((offset % 4) == 2)
+ tmp = (tmp & 0xff00ffff) | ((val & 0xff) << 16);
+ if ((offset % 4) == 3)
+ tmp = (tmp & 0x00ffffff) | ((val & 0xff) << 24);
+
+ if (bus == 0)
+ pci0WriteConfigReg(offset, device, tmp);
+// if (bus == 1) pci1WriteConfigReg (offset,device,tmp);
+ DBG(KERN_INFO "rr: wcb dev %d, offset %x, val %x\n", dev, offset,
+ val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static void galileo_pcibios_set_master(struct pci_dev *dev)
+{
+ u16 cmd;
+
+ DBG(KERN_INFO "rr: galileo_pcibios_set_master\n");
+
+ galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MASTER;
+ galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+ DBG("PCI: Enabling device %s (%04x)\n", dev->slot_name, cmd);
+}
+
+/* Externally-expected functions. Do not change function names */
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+ u16 cmd, old_cmd;
+ u16 tmp;
+ u8 tmp1;
+ int idx;
+ struct resource *r;
+
+ DBG(KERN_INFO "rr: pcibios_enable_resources\n");
+
+ galileo_pcibios_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for (idx = 0; idx < 6; idx++) {
+ r = &dev->resource[idx];
+ DBG(KERN_INFO
+ "rr: BAR %d, start %lx, end %lx, flags %lx\n", idx,
+ r->start, r->end, r->flags);
+ if (!r->start && r->end) {
+ printk(KERN_ERR
+ "PCI: Device %s not available because of resource collisions\n",
+ dev->slot_name);
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (cmd != old_cmd) {
+ DBG(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n",
+ dev->slot_name, old_cmd, cmd);
+ galileo_pcibios_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+
+ /*
+ Let's fix up the latency timer and cache line size here. Cache line size =
+ 32 bytes / sizeof dword (4) = 8.
+ Latency timer must be > 8. 32 is random but appears to work.
+ */
+ galileo_pcibios_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+ if (tmp1 != 8) {
+ DBG(KERN_INFO
+ "rr: PCI setting cache line size to 8 from %d\n",
+ tmp1);
+ galileo_pcibios_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
+ 8);
+ }
+ galileo_pcibios_read_config_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+ if (tmp1 < 32) {
+ DBG(KERN_INFO
+ "rr: PCI setting latency timer to 32 from %d\n", tmp1);
+ galileo_pcibios_write_config_byte(dev, PCI_LATENCY_TIMER,
+ 32);
+ }
+
+ return 0;
+}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+ DBG(KERN_INFO "rr: pcibios_enable_device\n");
+ return pcibios_enable_resources(dev);
+}
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
+{
+ u32 new, check;
+ int reg;
+
+ DBG(KERN_INFO "rr: pcibios_update_resource\n");
+ return;
+
+ new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+ if (resource < 6) {
+ reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+ } else if (resource == PCI_ROM_RESOURCE) {
+ res->flags |= PCI_ROM_ADDRESS_ENABLE;
+ reg = dev->rom_base_reg;
+ } else {
+ /* Somebody might have asked allocation of a non-standard resource */
+ return;
+ }
+
+ pci_write_config_dword(dev, reg, new);
+ pci_read_config_dword(dev, reg, &check);
+ if ((new ^ check) &
+ ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+ PCI_BASE_ADDRESS_MEM_MASK)) {
+ DBG(KERN_ERR "PCI: Error while updating region "
+ "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+ new, check);
+ }
+}
+
+void pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size)
+{
+ struct pci_dev *dev = data;
+
+ DBG(KERN_INFO "pcibios_align_resource\n");
+
+ if (res->flags & IORESOURCE_IO) {
+ unsigned long start = res->start;
+
+ /* We need to avoid collisions with `mirrored' VGA ports
+ and other strange ISA hardware, so we always want the
+ addresses kilobyte aligned. */
+ if (size > 0x100) {
+ DBG(KERN_ERR "PCI: I/O Region %s/%d too large"
+ " (%ld bytes)\n", dev->slot_name,
+ dev->resource - res, size);
+ }
+
+ start = (start + 1024 - 1) & ~(1024 - 1);
+ res->start = start;
+ }
+}
+
+/********************************************************************
+ *structure galileo_pci_ops
+ *
+ *This structure holds the pointers for the PCI configuration space
+ *access, and the fixup for the interrupts.
+ *This structure is registered to the operating system in boot time
+ *
+ *********************************************************************/
+
+struct pci_ops galileo_pci_ops = {
+ galileo_pcibios_read_config_byte,
+ galileo_pcibios_read_config_word,
+ galileo_pcibios_read_config_dword,
+ galileo_pcibios_write_config_byte,
+ galileo_pcibios_write_config_word,
+ galileo_pcibios_write_config_dword
+};
+
+/********************************************************************
+ *galileo_pcibios_fixup_bus -
+ *
+ *After detecting all agents over the PCI , this function is called
+ *in order to give an interrupt number for each PCI device starting
+ *from IRQ 20. It does also enables master for each device.
+ *
+ *Inputs :
+ *mem_start , mem_end are not relevant in MIPS architecture.
+ *
+ *Outpus :
+ *return always mem_start
+ *********************************************************************/
+static void __init galileo_pcibios_fixup_bus(struct pci_bus *bus)
+{
+ unsigned int Current_IRQ = 20;
+ struct pci_bus *current_bus = bus;
+ struct pci_dev *devices;
+ struct list_head *devices_link;
+
+ list_for_each(devices_link, &(current_bus->devices)) {
+ devices = pci_dev_b(devices_link);
+ if (devices != NULL) {
+ devices->irq = Current_IRQ++;
+
+ /* Assign an interrupt number for the device */
+ galileo_pcibios_write_config_byte(devices,
+ PCI_INTERRUPT_LINE,
+ Current_IRQ);
+ galileo_pcibios_set_master(devices);
+
+ }
+ }
+
+}
+
+struct pci_fixup pcibios_fixups[] = {
+// { PCI_FIXUP_HEADER, 0x4620, 0x11ab, galileo_pcibios_fixup },
+ {0}
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+ DBG(KERN_INFO "rr: pcibios_fixup_bus\n");
+ galileo_pcibios_fixup_bus(c);
+}
+
+/*
+ This code was derived from Galileo Technology's example
+ and significantly reworked.
+
+ This is very simple. It does not scan multiple function devices. It does not
+ scan behind bridges. Those would be simple to implement, but we don't currently
+ need this.
+*/
+
+static void __init scan_and_initialize_pci(void)
+{
+ struct pci_device pci_devices[MAX_PCI_DEVS];
+
+ if (scan_pci_bus(pci_devices)) {
+ allocate_pci_space(pci_devices);
+ }
+}
+
+/*
+ This is your basic PCI scan. It goes through each slot and checks to
+ see if there's something that responds. If so, then get the size and
+ type of each of the responding BARs. Save them for later.
+*/
+
+static u32 __init scan_pci_bus(struct pci_device *pci_devices)
+{
+ u32 arrayCounter = 0;
+ u32 memType;
+ u32 memSize;
+ u32 pci_slot, bar;
+ u32 id;
+ u32 c18RegValue;
+ struct pci_dev device;
+
+ DBG(KERN_INFO "rr: scan_pci_bus\n");
+
+ /*
+ According to PCI REV 2.1 MAX agents on the bus are 21.
+ We don't bother scanning ourselves (slot 0).
+ */
+ for (pci_slot = 1; pci_slot < 22; pci_slot++) {
+
+ device.devfn = PCI_DEVFN(pci_slot, 0);
+ id = pci0ReadConfigReg(PCI_VENDOR_ID, &device);
+
+ /* Check for a PCI Master Abort (nothing responds in the slot) */
+ GT_READ(GT_INTRCAUSE_OFS, &c18RegValue);
+ /* Clearing bit 18 of in the Cause Register 0xc18 by writting 0. */
+ GT_WRITE(GT_INTRCAUSE_OFS, (c18RegValue & 0xfffbffff));
+ if ((id != 0xffffffff) && !(c18RegValue & 0x40000)) {
+ DBG(KERN_INFO "rr: found device %x, slot %d\n", id,
+ pci_slot);
+ pci_devices[arrayCounter].slot = pci_slot;
+ for (bar = 0; bar < 6; bar++) {
+ memType =
+ pci0ReadConfigReg(PCI_BASE_ADDRESS_0 +
+ (bar * 4), &device);
+ pci_devices[arrayCounter].BARtype[bar] =
+ memType & 1;
+ pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+ (bar * 4), &device,
+ 0xffffffff);
+ memSize =
+ pci0ReadConfigReg(PCI_BASE_ADDRESS_0 +
+ (bar * 4), &device);
+ if (memType & 1) { /* IO space */
+ pci_devices[arrayCounter].
+ BARsize[bar] =
+ ~(memSize & 0xfffffffc) + 1;
+ } else { /* memory space */
+ pci_devices[arrayCounter].
+ BARsize[bar] =
+ ~(memSize & 0xfffffff0) + 1;
+ }
+ DBG(KERN_INFO
+ "rr: BAR %d, type %d, size %x\n", bar,
+ (memType & 1),
+ pci_devices[arrayCounter].
+ BARsize[bar]);
+ } /* BAR counter */
+
+ arrayCounter++;
+ }
+ /* found a device */
+ } /* slot counter */
+
+ DBG(KERN_INFO "rr: found %d devices\n", arrayCounter);
+ if (arrayCounter < MAX_PCI_DEVS) {
+ pci_devices[arrayCounter].slot = -1;
+ }
+ return (arrayCounter);
+}
+
+#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
+#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
+
+/*
+ This function goes through the list of devices and allocates the BARs in
+ either IO or MEM space. It does it in order of size, which will limit the
+ amount of fragmentation we have in the IO and MEM spaces.
+*/
+
+static void __init allocate_pci_space(struct pci_device *pci_devices)
+{
+ u32 count, maxcount, bar;
+ u32 maxSize, maxDevice, maxBAR;
+ u32 alignto;
+ u32 base;
+ u32 pci0_mem_base = pci0GetMemory0Base();
+ u32 pci0_io_base = pci0GetIOspaceBase();
+ struct pci_dev device;
+
+ DBG(KERN_INFO "rr: allocate_pci_space\n");
+
+ DBG(KERN_INFO "pci0_io_base %x\n", pci0_io_base);
+ DBG(KERN_INFO "pci0_mem_base %x\n", pci0_mem_base);
+
+ /* How many PCI devices do we have? */
+ maxcount = MAX_PCI_DEVS;
+ for (count = 0; count < MAX_PCI_DEVS; count++) {
+ if (pci_devices[count].slot == -1) {
+ maxcount = count;
+ break;
+ }
+ }
+
+// DBG(KERN_INFO "Found %d devices\n", maxcount);
+
+ do {
+ /* Find the largest size BAR we need to allocate */
+ maxSize = 0;
+ for (count = 0; count < maxcount; count++) {
+ for (bar = 0; bar < 6; bar++) {
+ if (pci_devices[count].BARsize[bar] >
+ maxSize) {
+ maxSize =
+ pci_devices[count].
+ BARsize[bar];
+ maxDevice = count;
+ maxBAR = bar;
+ }
+ }
+ }
+
+ /*
+ We've found the largest BAR. Allocate it into IO or
+ mem space. We don't idiot check the bases to make
+ sure they haven't overflowed the current size for that aperture.
+
+ Don't bother to enable the device's IO or MEM space here. That will
+ be done in pci_enable_resources if the device is activated by a driver.
+ */
+ if (maxSize) {
+ device.devfn =
+ PCI_DEVFN(pci_devices[maxDevice].slot, 0);
+ if (pci_devices[maxDevice].BARtype[maxBAR] == 1) {
+ alignto = MAX(0x1000, maxSize);
+ base = ALIGN(pci0_io_base, alignto);
+ pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+ (maxBAR * 4), &device,
+ base | 0x1);
+ pci0_io_base = base + alignto;
+ DBG(KERN_INFO
+ "Device %d BAR %d address %x\n",
+ pci_devices[maxDevice].slot, maxBAR,
+ base);
+ DBG(KERN_INFO "New IO base %x\n",
+ pci0_io_base);
+ } else {
+ alignto = MAX(0x1000, maxSize);
+ base = ALIGN(pci0_mem_base, alignto);
+ pci0WriteConfigReg(PCI_BASE_ADDRESS_0 +
+ (maxBAR * 4), &device,
+ base);
+ pci0_mem_base = base + alignto;
+ DBG(KERN_INFO
+ "Device %d BAR %d address %x\n",
+ pci_devices[maxDevice].slot, maxBAR,
+ base);
+ DBG(KERN_INFO "New mem base %x\n",
+ pci0_mem_base);
+ }
+ /*
+ This entry is finished. Remove it from the list we'll scan.
+ */
+ pci_devices[maxDevice].BARsize[maxBAR] = 0;
+ }
+ } while (maxSize);
+}
+
+void __init pcibios_init(void)
+{
+
+ u32 tmp;
+ struct pci_dev controller;
+
+ controller.devfn = SELF;
+
+ DBG(KERN_INFO "rr: pcibios_init\n");
+ GT_READ(GT_PCI0_CMD_OFS, &tmp);
+ DBG(KERN_INFO "rr: PCI0 command - %x\n", tmp);
+ GT_READ(GT_PCI0_BARE_OFS, &tmp);
+ DBG(KERN_INFO "rr: BAR0 - %x\n", tmp);
+
+/*
+ You have to enable bus mastering to configure any other
+ card on the bus.
+*/
+ tmp = pci0ReadConfigReg(PCI_COMMAND, &controller);
+ DBG(KERN_INFO "rr: command/status - %x\n", tmp);
+ tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR;
+ DBG(KERN_INFO "rr: new command/status - %x\n", tmp);
+ pci0WriteConfigReg(PCI_COMMAND, &controller, tmp);
+
+ /* This scans the PCI bus and sets up initial values. */
+ scan_and_initialize_pci();
+
+ /* Reset PCI I/O and PCI MEM values to ones supported
+ by EVM.
+ */
+ ioport_resource.start = 0x10000000;
+ ioport_resource.end = 0x11ffffff; /* 32 MB */
+ iomem_resource.start = 0x12000000;
+ iomem_resource.end = 0x13ffffff; /* 32 MB */
+
+ pci_scan_bus(0, &galileo_pci_ops, NULL);
+
+}
+
+char *pcibios_setup(char *str)
+{
+ printk(KERN_INFO "rr: pcibios_setup\n");
+ /* Nothing to do for now. */
+
+ return str;
+}
+
+void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
+ dma_addr_t * dma_handle)
+{
+ void *ret;
+ int gfp = GFP_ATOMIC;
+
+ if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
+ gfp |= GFP_DMA;
+ ret = (void *) __get_free_pages(gfp, get_order(size));
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_bus(ret);
+ }
+ return ret;
+}
+
+#if 1
+void pci_free_consistent(struct pci_dev *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ free_pages((unsigned long) vaddr, get_order(size));
+}
+#endif
+
+#endif /* CONFIG_PCI */
diff --git a/arch/mips/galileo-boards/ev64120/promcon.c b/arch/mips/galileo-boards/ev64120/promcon.c
new file mode 100644
index 000000000..83d3006f9
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/promcon.c
@@ -0,0 +1,80 @@
+/*
+ * Wrap-around code for a console using the
+ * SGI PROM io-routines.
+ *
+ * Copyright (c) 1999 Ulf Carlsson
+ *
+ * Derived from DECstation promcon.c
+ * Copyright (c) 1998 Harald Koerfgen
+ */
+
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+/*
+#include <asm/sgialib.h>
+*/
+
+static void prom_console_write(struct console *co, const char *s,
+ unsigned count)
+{
+ extern int CONSOLE_CHANNEL; // The default serial port
+ unsigned i;
+ /*
+ * Now, do each character
+ */
+ for (i = 0; i < count; i++) {
+ if (*s == 10)
+ serial_putc(CONSOLE_CHANNEL, 13);
+ serial_putc(CONSOLE_CHANNEL, *s++);
+ }
+}
+int prom_getchar(void)
+{
+ return 0;
+}
+static int prom_console_wait_key(struct console *co)
+{
+ return prom_getchar();
+}
+
+static int __init prom_console_setup(struct console *co, char *options)
+{
+
+ return 0;
+}
+
+static kdev_t prom_console_device(struct console *c)
+{
+ return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static struct console sercons = {
+ "ttyS",
+ prom_console_write,
+ NULL,
+ prom_console_device,
+ prom_console_wait_key,
+ NULL,
+ prom_console_setup,
+ CON_PRINTBUFFER,
+ -1,
+ 0,
+ NULL
+};
+
+
+/*
+ * Register console.
+ */
+
+void gal_serial_console_init(void)
+{
+ // serial_init();
+ //serial_set(115200);
+
+ register_console(&sercons);
+}
diff --git a/arch/mips/galileo-boards/ev64120/reset.c b/arch/mips/galileo-boards/ev64120/reset.c
new file mode 100644
index 000000000..b145a3446
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/reset.c
@@ -0,0 +1,73 @@
+/*
+ * EVB96100 -Galileo reset subroutines
+ *
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/system.h>
+
+/********************************************************************
+ *galileo_machine_restart -
+ *
+ *Restart the machine
+ *
+ *
+ *Inputs :
+ *command - not used
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+void galileo_machine_restart(char *command)
+{
+ *(volatile char *) 0xbc000000 = 0x0f;
+ /*
+ * Ouch, we're still alive ... This time we take the silver bullet ...
+ * ... and find that we leave the hardware in a state in which the
+ * kernel in the flush locks up somewhen during of after the PCI
+ * detection stuff.
+ */
+ set_cp0_status((ST0_BEV | ST0_ERL), (ST0_BEV | ST0_ERL));
+ set_cp0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
+ flush_cache_all();
+ write_32bit_cp0_register(CP0_WIRED, 0);
+ __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
+}
+
+/********************************************************************
+ *galileo_machine_halt -
+ *
+ *Halt the machine
+ *
+ *
+ *Inputs :
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+void galileo_machine_halt(void)
+{
+ printk("\n** You can safely turn off the power\n");
+ while (1) {
+ }
+}
+
+/********************************************************************
+ *galileo_machine_power_off -
+ *
+ *Halt the machine
+ *
+ *
+ *Inputs :
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+void galileo_machine_power_off(void)
+{
+ galileo_machine_halt();
+}
diff --git a/arch/mips/galileo-boards/ev64120/serialGT.c b/arch/mips/galileo-boards/ev64120/serialGT.c
new file mode 100644
index 000000000..3d2d4452d
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/serialGT.c
@@ -0,0 +1,212 @@
+/*
+ * serialGT.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Low Level Serial Port control for use
+ * with the Galileo EVB64120A MIPS eval board and
+ * its on board two channel 16552 Uart.
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+// Note:
+// Serial CHANNELS - 0 is the bottom connector of evb64120A.
+// (The one that maps to the "B" channel of the
+// board's uart)
+// 1 is the top connector of evb64120A.
+// (The one that maps to the "A" channel of the
+// board's uart)
+int DEBUG_CHANNEL = 0; // See Note Above
+int CONSOLE_CHANNEL = 1; // See Note Above
+
+#define DUART 0xBD000000 /* Base address of Uart. */
+#define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA
+ register set of the 16552 Uart device.
+ DUART+0 gets you to the ChanB register set.
+ */
+#define DUART_DELTA 0x4
+#define FIFO_ENABLE 0x07
+#define INT_ENABLE 0x04 /* default interrupt mask */
+
+#define RBR 0x00
+#define THR 0x00
+#define DLL 0x00
+#define IER 0x01
+#define DLM 0x01
+#define IIR 0x02
+#define FCR 0x02
+#define LCR 0x03
+#define MCR 0x04
+#define LSR 0x05
+#define MSR 0x06
+#define SCR 0x07
+
+#define LCR_DLAB 0x80
+#define XTAL 1843200
+#define LSR_THRE 0x20
+#define LSR_BI 0x10
+#define LSR_DR 0x01
+#define MCR_LOOP 0x10
+#define ACCESS_DELAY 0x10000
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+int inreg(int channel, int reg)
+{
+ int val;
+ val =
+ *((volatile unsigned char *) DUART +
+ (channel * CHANNELOFFSET) + (reg * DUART_DELTA));
+ return val;
+}
+
+/******************************
+ Routine:
+ Description:
+ ******************************/
+void outreg(int channel, int reg, unsigned char val)
+{
+ *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET)
+ + (reg * DUART_DELTA)) = val;
+}
+
+/******************************
+ Routine:
+ Description:
+ Initialize the device driver.
+ ******************************/
+void serial_init(int channel)
+{
+ /*
+ * Configure active port, (CHANNELOFFSET already set.)
+ *
+ * Set 8 bits, 1 stop bit, no parity.
+ *
+ * LCR<7> 0 divisor latch access bit
+ * LCR<6> 0 break control (1=send break)
+ * LCR<5> 0 stick parity (0=space, 1=mark)
+ * LCR<4> 0 parity even (0=odd, 1=even)
+ * LCR<3> 0 parity enable (1=enabled)
+ * LCR<2> 0 # stop bits (0=1, 1=1.5)
+ * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8)
+ */
+ outreg(channel, LCR, 0x3);
+
+ outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */
+
+ outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */
+}
+
+/******************************
+ Routine:
+ Description:
+ Set the baud rate.
+ ******************************/
+void serial_set(int channel, unsigned long baud)
+{
+ unsigned char sav_lcr;
+
+ /*
+ * Enable access to the divisor latches by setting DLAB in LCR.
+ *
+ */
+ sav_lcr = inreg(channel, LCR);
+
+#if 0
+ /*
+ * Set baud rate
+ */
+ outreg(channel, LCR, LCR_DLAB | sav_lcr);
+ // outreg(DLL,(XTAL/(16*2*(baud))-2));
+ outreg(channel, DLL, XTAL / (16 * baud));
+ // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8);
+ outreg(channel, DLM, (XTAL / (16 * baud)) >> 8);
+#else
+ /*
+ * Note: Set baud rate, hardcoded here for rate of 115200
+ * since became unsure of above "buad rate" algorithm (??).
+ */
+ outreg(channel, LCR, 0x83);
+ outreg(channel, DLM, 0x00); // See note above
+ outreg(channel, DLL, 0x02); // See note above.
+ outreg(channel, LCR, 0x03);
+#endif
+
+ /*
+ * Restore line control register
+ */
+ outreg(channel, LCR, sav_lcr);
+}
+
+
+/******************************
+ Routine:
+ Description:
+ Transmit a character.
+ ******************************/
+void serial_putc(int channel, int c)
+{
+ while ((inreg(channel, LSR) & LSR_THRE) == 0);
+ outreg(channel, THR, c);
+}
+
+/******************************
+ Routine:
+ Description:
+ Read a received character if one is
+ available. Return -1 otherwise.
+ ******************************/
+int serial_getc(int channel)
+{
+ if (inreg(channel, LSR) & LSR_DR) {
+ return inreg(channel, RBR);
+ }
+ return -1;
+}
+
+/******************************
+ Routine:
+ Description:
+ Used by embedded gdb client. (example; gdb-stub.c)
+ ******************************/
+char getDebugChar()
+{
+ int val;
+ while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in.
+ return (char) val;
+}
+
+/******************************
+ Routine:
+ Description:
+ Used by embedded gdb target. (example; gdb-stub.c)
+ ******************************/
+void putDebugChar(char c)
+{
+ serial_putc(DEBUG_CHANNEL, (int) c);
+}
diff --git a/arch/mips/galileo-boards/ev64120/setup.c b/arch/mips/galileo-boards/ev64120/setup.c
new file mode 100644
index 000000000..874245fa8
--- /dev/null
+++ b/arch/mips/galileo-boards/ev64120/setup.c
@@ -0,0 +1,234 @@
+/*
+ * setup.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * Galileo Evaluation Boards - board dependent boot routines
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/timex.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pci.h>
+#include <asm/processor.h>
+#include <asm/ptrace.h>
+#include <asm/reboot.h>
+#include <asm/mc146818rtc.h>
+#include <linux/version.h>
+#include <linux/bootmem.h>
+
+extern struct rtc_ops no_rtc_ops;
+struct rtc_ops *rtc_ops;
+
+/* These functions are used for rebooting or halting the machine*/
+extern void galileo_machine_restart(char *command);
+extern void galileo_machine_halt(void);
+extern void galileo_machine_power_off(void);
+/*
+ *This structure holds pointers to the pci configuration space accesses
+ *and interrupts allocating routine for device over the PCI
+ */
+extern struct pci_ops galileo_pci_ops;
+
+extern unsigned long mips_machgroup;
+
+char arcs_cmdline[CL_SIZE] = { "console=ttyS0,115200 "
+ "root=/dev/nfs rw nfsroot=192.168.1.1:/mnt/disk2/fs.gal "
+ "ip=192.168.1.211:192.168.1.1:::gt::"
+};
+
+//struct eeprom_parameters eeprom_param;
+
+/*
+ * These two functions are added because arch/mips/mm/init.c needs them
+ * basically they do nothing
+ */
+void __init prom_fixup_mem_map(unsigned long start, unsigned long end)
+{
+}
+
+void prom_free_prom_memory(void)
+{
+}
+
+int /*__init*/ page_is_ram(unsigned long pagenr)
+{
+ return 1;
+}
+
+void (*board_time_init) (struct irqaction * irq);
+
+static unsigned char galileo_rtc_read_data(unsigned long addr)
+{
+ return 0;
+}
+
+static void galileo_rtc_write_data(unsigned char data, unsigned long addr)
+{
+}
+
+static int galileo_rtc_bcd_mode(void)
+{
+ return 0;
+}
+
+struct rtc_ops galileo_rtc_ops = {
+ &galileo_rtc_read_data,
+ &galileo_rtc_write_data,
+ &galileo_rtc_bcd_mode
+};
+
+/********************************************************************
+ *ev64120_setup -
+ *
+ *Initializes basic routines and structures pointers, memory size (as
+ *given by the bios and saves the command line.
+ *
+ *
+ *Inputs :
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+extern void galileo_time_init();
+void ev64120_setup(void)
+{
+ unsigned int i, j;
+
+ //printk(KERN_INFO "ev64120_setup\n");
+
+ _machine_restart = galileo_machine_restart;
+ _machine_halt = galileo_machine_halt;
+ _machine_power_off = galileo_machine_power_off;
+
+ rtc_ops = &galileo_rtc_ops;
+
+ board_time_init = galileo_time_init;
+ mips_io_port_base = KSEG1;
+ mips_memory_upper = 32 * 1024 * 1024 | KSEG0;
+ set_cp0_status(ST0_FR, 0);
+
+#ifdef CONFIG_L2_L3_CACHE
+#error "external cache not implemented yet"
+ config_register = read_32bit_cp0_register(CP0_CONFIG);
+ printk("\n\n\nchecking second level cache cp0_config = %08lx\n",
+ config_register);
+ if (config_register & CONF_SC) { // second/third level cache available
+ config_register = config_register & (1 << 12);
+ write_32bit_cp0_register(CP0_CONFIG, config_register);
+ printk
+ ("\n\n\nchecking second level cache cp0_config = %08lx\n",
+ config_register);
+ }
+#endif
+
+}
+
+/********************************************************************
+ *SetUpBootInfo -
+ *
+ *This function is called at very first stages of kernel startup.
+ *It specifies for the kernel the evaluation board that the linux
+ *is running on. Then it saves the eprom parameters that holds the
+ *command line, memory size etc...
+ *
+ *Inputs :
+ *argc - nothing
+ *argv - holds a pointer to the eprom parameters
+ *envp - nothing
+ *
+ *Outpus :
+ *
+ *********************************************************************/
+void SetUpBootInfo(int argc, char **argv, char **envp)
+{
+ mips_machgroup = MACH_GROUP_GALILEO;
+ mips_machtype = MACH_EV64120A;
+}
+
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+
+extern int _end;
+
+unsigned long mem_size;
+int __init prom_init(int a, char **b, char **c, int *d)
+{
+ unsigned long free_start, free_end, start_pfn, bootmap_size;
+
+ mips_machgroup = MACH_GROUP_GALILEO;
+ /* 32 MB */
+ mem_size = 32 << 20;
+ mips_memory_upper = 0x81000000;
+
+ free_start = PHYSADDR(PFN_ALIGN(&_end));
+ free_end = mem_size;
+ start_pfn = PFN_UP((unsigned long) &_end);
+
+ /* Register all the contiguous memory with the bootmem allocator
+ and free it. Be careful about the bootmem freemap. */
+ bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT);
+
+ /* Free the entire available memory after the _end symbol. */
+ free_start += bootmap_size;
+ free_bootmem(free_start, free_end - free_start);
+ return 0;
+}
+
+#if 0
+void prom_free_prom_memory(void)
+{
+}
+
+int page_is_ram(unsigned long pagenr)
+{
+ if (pagenr < (mem_size >> PAGE_SHIFT))
+ return 1;
+ return 0;
+}
+
+void turn_on_debug_led();
+
+void turn_on_debug_led()
+{
+#define DEBUG_LIGHT (*(char *)0xbc080000)
+ DEBUG_LIGHT = 1;
+}
+#endif