Add support for AP1000 board.
Patch by James MacAulay, 07 Oct 2005
diff --git a/CHANGELOG b/CHANGELOG
index 496a3b6..66994b8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,9 @@
 Changes for U-Boot 1.1.4:
 ======================================================================
 
+* Add support for AP1000 board.
+  Patch by James MacAulay, 07 Oct 2005
+
 * Eliminate hard-coded address of Ethernet transfer buffer on at91rm9200
   Patch by Anders Larsen, 07 Oct 2005
 
diff --git a/CREDITS b/CREDITS
index 4ea3c74..23055cb 100644
--- a/CREDITS
+++ b/CREDITS
@@ -443,3 +443,8 @@
 E: azu@sysgo.de
 D: Overall improvements on StrongARM, ARM720TDMI; Support for Tuxscreen; initial PCMCIA support for ARM
 W: www.elinos.com
+
+N: James MacAulay
+E: james.macaulay@amirix.com
+D: Suppport for Amirix AP1000
+W: www.amirix.com
diff --git a/MAKEALL b/MAKEALL
index 0472cfb..79be0d8 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -61,18 +61,18 @@
 #########################################################################
 
 LIST_4xx="	\
-	ADCIOP		AR405		ASH405		bubinga		\
-	CANBT		CPCI2DP		CPCI405		CPCI4052	\
-	CPCI405AB	CPCI440		CPCIISER4	CRAYL1		\
-	csb272		csb472		DASA_SIM	DP405		\
-	DU405		ebony		ERIC		EXBITGEN	\
-	G2000		HUB405		JSE		KAREF		\
-	METROBOX	MIP405		MIP405T		ML2		\
-	ml300		ocotea		OCRTC		ORSG		\
-	PCI405		PIP405		PLU405		PMC405		\
-	PPChameleonEVB	sbc405		VOH405		W7OLMC		\
-	W7OLMG		walnut		WUH405		XPEDITE1K	\
-	yellowstone	yosemite        \
+	ADCIOP		AP1000		AR405		ASH405		\
+	bubinga		CANBT		CPCI2DP		CPCI405		\
+	CPCI4052	CPCI405AB	CPCI440		CPCIISER4	\
+	CRAYL1		csb272		csb472		DASA_SIM	\
+	DP405		DU405		ebony		ERIC		\
+	EXBITGEN	G2000		HUB405		JSE		\
+	KAREF		METROBOX	MIP405		MIP405T		\
+	ML2		ml300		ocotea		OCRTC		\
+	ORSG		PCI405		PIP405		PLU405		\
+	PMC405		PPChameleonEVB	sbc405		VOH405		\
+	W7OLMC		W7OLMG		walnut		WUH405		\
+	XPEDITE1K	yellowstone	yosemite        \
 "
 
 #########################################################################
diff --git a/Makefile b/Makefile
index 86cb6a8..6ce5416 100644
--- a/Makefile
+++ b/Makefile
@@ -721,6 +721,9 @@
 ADCIOP_config:	unconfig
 	@./mkconfig $(@:_config=) ppc ppc4xx adciop esd
 
+AP1000_config:unconfig
+	@./mkconfig $(@:_config=) ppc ppc4xx ap1000 amirix
+
 APC405_config:	unconfig
 	@./mkconfig $(@:_config=) ppc ppc4xx apc405 esd
 
diff --git a/README b/README
index 419ae0d..71e9dc9 100644
--- a/README
+++ b/README
@@ -261,44 +261,45 @@
 		PowerPC based boards:
 		---------------------
 
-		CONFIG_ADCIOP		CONFIG_GEN860T		CONFIG_PCI405
-		CONFIG_ADS860		CONFIG_GENIETV		CONFIG_PCIPPC2
-		CONFIG_AMX860		CONFIG_GTH		CONFIG_PCIPPC6
-		CONFIG_AR405		CONFIG_gw8260		CONFIG_pcu_e
-		CONFIG_BAB7xx		CONFIG_hermes		CONFIG_PIP405
-		CONFIG_c2mon		CONFIG_hymod		CONFIG_PM826
-		CONFIG_CANBT		CONFIG_IAD210		CONFIG_ppmc8260
-		CONFIG_CCM		CONFIG_ICU862		CONFIG_QS823
-		CONFIG_CMI		CONFIG_IP860		CONFIG_QS850
-		CONFIG_cogent_mpc8260	CONFIG_IPHASE4539	CONFIG_QS860T
-		CONFIG_cogent_mpc8xx	CONFIG_IVML24		CONFIG_RBC823
-		CONFIG_CPCI405		CONFIG_IVML24_128	CONFIG_RPXClassic
-		CONFIG_CPCI4052		CONFIG_IVML24_256	CONFIG_RPXlite
-		CONFIG_CPCIISER4	CONFIG_IVMS8		CONFIG_RPXsuper
-		CONFIG_CPU86		CONFIG_IVMS8_128	CONFIG_rsdproto
-		CONFIG_CRAYL1		CONFIG_IVMS8_256	CONFIG_sacsng
-		CONFIG_CSB272		CONFIG_JSE		CONFIG_Sandpoint8240
-		CONFIG_CU824		CONFIG_LANTEC		CONFIG_Sandpoint8245
-		CONFIG_DASA_SIM		CONFIG_lwmon		CONFIG_sbc8260
-		CONFIG_DB64360		CONFIG_MBX		CONFIG_sbc8560
-		CONFIG_DB64460		CONFIG_MBX860T		CONFIG_SM850
-		CONFIG_DU405		CONFIG_MHPC		CONFIG_SPD823TS
-		CONFIG_DUET_ADS		CONFIG_MIP405		CONFIG_STXGP3
-		CONFIG_EBONY		CONFIG_MOUSSE		CONFIG_SXNI855T
-		CONFIG_ELPPC		CONFIG_MPC8260ADS	CONFIG_TQM823L
-		CONFIG_ELPT860		CONFIG_MPC8540ADS	CONFIG_TQM8260
-		CONFIG_ep8260		CONFIG_MPC8540EVAL	CONFIG_TQM850L
-		CONFIG_ERIC		CONFIG_MPC8560ADS	CONFIG_TQM855L
-		CONFIG_ESTEEM192E	CONFIG_MUSENKI		CONFIG_TQM860L
-		CONFIG_ETX094		CONFIG_MVS1		CONFIG_TTTech
-		CONFIG_EVB64260		CONFIG_NETPHONE		CONFIG_UTX8245
-		CONFIG_FADS823		CONFIG_NETTA		CONFIG_V37
-		CONFIG_FADS850SAR	CONFIG_NETVIA		CONFIG_W7OLMC
-		CONFIG_FADS860T		CONFIG_NX823		CONFIG_W7OLMG
-		CONFIG_FLAGADM		CONFIG_OCRTC		CONFIG_WALNUT
-		CONFIG_FPS850L		CONFIG_ORSG		CONFIG_ZPC1900
-		CONFIG_FPS860L		CONFIG_OXC		CONFIG_ZUMA
-
+		CONFIG_ADCIOP		CONFIG_GEN860T		CONFIG_PCIPPC2
+		CONFIG_ADS860		CONFIG_GENIETV		CONFIG_PCIPPC6
+		CONFIG_AMX860		CONFIG_GTH		CONFIG_pcu_e
+		CONFIG_AP1000		CONFIG_gw8260		CONFIG_PIP405
+		CONFIG_AR405		CONFIG_hermes		CONFIG_PM826
+		CONFIG_BAB7xx		CONFIG_hymod		CONFIG_ppmc8260
+		CONFIG_c2mon		CONFIG_IAD210		CONFIG_QS823
+		CONFIG_CANBT		CONFIG_ICU862		CONFIG_QS850
+		CONFIG_CCM		CONFIG_IP860		CONFIG_QS860T
+		CONFIG_CMI		CONFIG_IPHASE4539	CONFIG_RBC823
+		CONFIG_cogent_mpc8260	CONFIG_IVML24		CONFIG_RPXClassic
+		CONFIG_cogent_mpc8xx	CONFIG_IVML24_128	CONFIG_RPXlite
+		CONFIG_CPCI405		CONFIG_IVML24_256	CONFIG_RPXsuper
+		CONFIG_CPCI4052		CONFIG_IVMS8		CONFIG_rsdproto
+		CONFIG_CPCIISER4	CONFIG_IVMS8_128	CONFIG_sacsng
+		CONFIG_CPU86		CONFIG_IVMS8_256	CONFIG_Sandpoint8240
+		CONFIG_CRAYL1		CONFIG_JSE		CONFIG_Sandpoint8245
+		CONFIG_CSB272		CONFIG_LANTEC		CONFIG_sbc8260
+		CONFIG_CU824		CONFIG_lwmon		CONFIG_sbc8560
+		CONFIG_DASA_SIM		CONFIG_MBX		CONFIG_SM850
+		CONFIG_DB64360		CONFIG_MBX860T		CONFIG_SPD823TS
+		CONFIG_DB64460		CONFIG_MHPC		CONFIG_STXGP3
+		CONFIG_DU405		CONFIG_MIP405		CONFIG_SXNI855T
+		CONFIG_DUET_ADS		CONFIG_MOUSSE		CONFIG_TQM823L
+		CONFIG_EBONY		CONFIG_MPC8260ADS	CONFIG_TQM8260
+		CONFIG_ELPPC		CONFIG_MPC8540ADS	CONFIG_TQM850L
+		CONFIG_ELPT860		CONFIG_MPC8540EVAL	CONFIG_TQM855L
+		CONFIG_ep8260		CONFIG_MPC8560ADS	CONFIG_TQM860L
+		CONFIG_ERIC		CONFIG_MUSENKI		CONFIG_TTTech
+		CONFIG_ESTEEM192E	CONFIG_MVS1		CONFIG_UTX8245
+		CONFIG_ETX094		CONFIG_NETPHONE		CONFIG_V37
+		CONFIG_EVB64260		CONFIG_NETTA		CONFIG_W7OLMC
+		CONFIG_FADS823		CONFIG_NETVIA		CONFIG_W7OLMG
+		CONFIG_FADS850SAR	CONFIG_NX823		CONFIG_WALNUT
+		CONFIG_FADS860T		CONFIG_OCRTC		CONFIG_ZPC1900
+		CONFIG_FLAGADM		CONFIG_ORSG		CONFIG_ZUMA
+		CONFIG_FPS850L		CONFIG_OXC			
+		CONFIG_FPS860L		CONFIG_PCI405
+								
 		ARM based boards:
 		-----------------
 
diff --git a/board/amirix/ap1000/Makefile b/board/amirix/ap1000/Makefile
new file mode 100644
index 0000000..4e1ef21
--- /dev/null
+++ b/board/amirix/ap1000/Makefile
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(BOARD).a
+
+OBJS	= $(BOARD).o flash.o serial.o pci.o powerspan.o
+SOBJS	= init.o
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $^
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/amirix/ap1000/ap1000.c b/board/amirix/ap1000/ap1000.c
new file mode 100644
index 0000000..743211f
--- /dev/null
+++ b/board/amirix/ap1000/ap1000.c
@@ -0,0 +1,672 @@
+/*
+ * amirix.c: ppcboot platform support for AMIRIX board
+ *
+ * Copyright 2002 Mind NV
+ * Copyright 2003 AMIRIX Systems Inc.
+ *
+ * http://www.mind.be/
+ * http://www.amirix.com/
+ *
+ * Author : Peter De Schrijver (p2@mind.be)
+ *          Frank Smith (smith@amirix.com)
+ *
+ * Derived from : Other platform support files in this tree, ml2
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire
+ * program is licensed under the GPL.
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+
+#include "powerspan.h"
+#include "ap1000.h"
+
+int board_pre_init (void)
+{
+    return 0;
+}
+
+/** serial number and platform display at startup */
+int checkboard (void)
+{
+    unsigned char *s = getenv ("serial#");
+    unsigned char *e;
+
+    /* After a loadace command, the SystemAce control register is left in a wonky state. */
+    /* this code did not work in board_pre_init */
+    unsigned char* p = (unsigned char*)AP1000_SYSACE_REGBASE;
+    p[SYSACE_CTRLREG0] = 0x0;
+
+    /* add platform and device to banner */
+    switch(get_device()){
+        case AP1xx_AP107_TARGET:{
+            puts(AP1xx_AP107_TARGET_STR);
+            break;
+        }
+        case AP1xx_AP120_TARGET:{
+            puts(AP1xx_AP120_TARGET_STR);
+            break;
+        }
+        case AP1xx_AP130_TARGET:{
+            puts(AP1xx_AP130_TARGET_STR);
+            break;
+        }
+        case AP1xx_AP1070_TARGET:{
+            puts(AP1xx_AP1070_TARGET_STR);
+            break;
+        }
+        case AP1xx_AP1100_TARGET:{
+            puts(AP1xx_AP1100_TARGET_STR);
+            break;
+        }
+        default:{
+            puts(AP1xx_UNKNOWN_STR);
+            break;
+        }
+    }
+    puts(AP1xx_TARGET_STR);
+    puts(" with ");
+
+    switch(get_platform()){
+        case AP100_BASELINE_PLATFORM:
+        case AP1000_BASELINE_PLATFORM:{
+            puts(AP1xx_BASELINE_PLATFORM_STR);
+            break;
+        }
+        case AP1xx_QUADGE_PLATFORM:{
+            puts(AP1xx_QUADGE_PLATFORM_STR);
+            break;
+        }
+        case AP1xx_MGT_REF_PLATFORM:{
+            puts(AP1xx_MGT_REF_PLATFORM_STR);
+            break;
+        }
+        case AP1xx_STANDARD_PLATFORM:{
+            puts(AP1xx_STANDARD_PLATFORM_STR);
+            break;
+        }
+        case AP1xx_DUAL_PLATFORM:{
+            puts(AP1xx_DUAL_PLATFORM_STR);
+            break;
+        }
+        case AP1xx_BASE_SRAM_PLATFORM:{
+            puts(AP1xx_BASE_SRAM_PLATFORM_STR);
+            break;
+        }
+        case AP1xx_PCI_PCB_TESTPLATFORM:
+        case AP1000_PCI_PCB_TESTPLATFORM:{
+            puts(AP1xx_PCI_PCB_TESTPLATFORM_STR);
+            break;
+        }
+        case AP1xx_DUAL_GE_MEZZ_TESTPLATFORM:{
+            puts(AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR);
+            break;
+        }
+        case AP1xx_SFP_MEZZ_TESTPLATFORM:{
+            puts(AP1xx_SFP_MEZZ_TESTPLATFORM_STR);
+            break;
+        }
+        default:{
+            puts(AP1xx_UNKNOWN_STR);
+            break;
+        }
+    }
+
+    if((get_platform() & AP1xx_TESTPLATFORM_MASK) != 0){
+        puts(AP1xx_TESTPLATFORM_STR);
+    }
+    else{
+        puts(AP1xx_PLATFORM_STR);
+    }
+
+    putc('\n');
+
+    puts ("Serial#: ");
+
+    if (!s) {
+        printf ("### No HW ID - assuming AMIRIX");
+    } else {
+        for (e = s; *e; ++e) {
+            if (*e == ' ')
+                break;
+        }
+
+        for (; s < e; ++s) {
+            putc (*s);
+        }
+    }
+
+    putc ('\n');
+
+    return (0);
+}
+
+
+long int initdram (int board_type)
+{
+    unsigned char *s = getenv ("dramsize");
+
+    if(s != NULL){
+        if((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))){
+            s += 2;
+        }
+        return simple_strtoul(s, NULL, 16);
+    }
+    else{
+        /* give all 64 MB */
+		return 64 * 1024 * 1024;
+    }
+}
+
+unsigned int get_platform(void){
+    unsigned int *revision_reg_ptr = (unsigned int *)AP1xx_FPGA_REV_ADDR;
+    return (*revision_reg_ptr & AP1xx_PLATFORM_MASK);
+}
+
+unsigned int get_device(void){
+    unsigned int *revision_reg_ptr = (unsigned int *)AP1xx_FPGA_REV_ADDR;
+
+    return (*revision_reg_ptr & AP1xx_TARGET_MASK);
+}
+
+#if 0  // loadace is not working; it appears to be a hardware issue with the system ace.
+/*
+   This function loads FPGA configurations from the SystemACE CompactFlash
+*/
+int do_loadace (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+    unsigned char *p = (unsigned char *)AP1000_SYSACE_REGBASE;
+    int cfg;
+
+    if((p[SYSACE_STATREG0] & 0x10) == 0) {
+        p[SYSACE_CTRLREG0] = 0x80;
+        printf ("\nNo CompactFlash Detected\n\n");
+        p[SYSACE_CTRLREG0] = 0x00;
+        return 1;
+    }
+
+    // reset configuration controller: |  0x80
+    // select cpflash                  & ~0x40
+    // cfg start                       |  0x20
+    // wait for cfgstart               & ~0x10
+    // force cfgmode:                  |  0x08
+    // do no force cfgaddr:            & ~0x04
+    // clear mpulock:                  & ~0x02
+    // do not force lock request       & ~0x01
+
+    p[SYSACE_CTRLREG0] = 0x80 | 0x20 | 0x08;
+    p[SYSACE_CTRLREG1] = 0x00;
+
+    // force config address if arg2 exists
+    if (argc == 2) {
+        cfg = simple_strtoul(argv[1], NULL, 10);
+
+        if(cfg > 7) {
+           printf ("\nInvalid Configuration\n\n");
+         p[SYSACE_CTRLREG0] = 0x00;
+           return 1;
+        }
+        // Set config address
+        p[SYSACE_CTRLREG1] = (cfg << 5);
+        // force cfgaddr
+        p[SYSACE_CTRLREG0] |= 0x04;
+
+    } else {
+        cfg = (p[SYSACE_STATREG1] & 0xE0) >> 5;
+    }
+
+    /* release configuration controller */
+    printf("\nLoading V2PRO with config %d...\n", cfg);
+    p[SYSACE_CTRLREG0] &= ~0x80;
+
+
+    while((p[SYSACE_STATREG1] & 0x01) == 0) {
+
+        if(p[SYSACE_ERRREG0] & 0x80) {
+            // attempting to load an invalid configuration makes the cpflash
+            // appear to be removed. Reset here to avoid that problem
+            p[SYSACE_CTRLREG0] = 0x80;
+            printf("\nConfiguration %d Read Error\n\n", cfg);
+            p[SYSACE_CTRLREG0] = 0x00;
+            return 1;
+        }
+    }
+
+    p[SYSACE_CTRLREG0] |= 0x20;
+
+    return 0;
+}
+#endif
+
+/** Console command to display and set the software reconfigure byte
+  * <pre>
+  * swconfig        - display the current value of the software reconfigure byte
+  * swconfig [#]    - change the software reconfigure byte to #
+  * </pre>
+  * @param  *cmdtp  [IN] as passed by run_command (ignored)
+  * @param  flag    [IN] as passed by run_command (ignored)
+  * @param  argc    [IN] as passed by run_command if 1, display, if 2 change
+  * @param  *argv[] [IN] contains the parameters to use
+  * @return
+  * <pre>
+  *      0 if passed
+  *     -1 if failed
+  * </pre>
+  */
+int do_swconfigbyte(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+    unsigned char *sector_buffer = NULL;
+    unsigned char input_char;
+    int write_result;
+    unsigned int  input_uint;
+
+    /* display value if no argument */
+    if(argc < 2){
+        printf("Software configuration byte is currently: 0x%02x\n",
+               *((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET)));
+        return 0;
+    }
+    else if(argc > 3){
+        printf("Too many arguments\n");
+        return -1;
+    }
+
+    /* if 3 arguments, 3rd argument is the address to use */
+    if(argc == 3){
+        input_uint = simple_strtoul(argv[1], NULL, 16);
+        sector_buffer = (unsigned char *)input_uint;
+    }
+    else{
+        sector_buffer = (unsigned char *)DEFAULT_TEMP_ADDR;
+    }
+
+    input_char = simple_strtoul(argv[1], NULL, 0);
+    if((input_char & ~SW_BYTE_MASK) != 0){
+        printf("Input of 0x%02x will be masked to 0x%02x\n",
+                input_char, (input_char & SW_BYTE_MASK));
+        input_char = input_char & SW_BYTE_MASK;
+    }
+
+    memcpy(sector_buffer, (void *)SW_BYTE_SECTOR_ADDR, SW_BYTE_SECTOR_SIZE);
+    sector_buffer[SW_BYTE_SECTOR_OFFSET] = input_char;
+
+
+    printf("Erasing Flash...");
+    if (flash_sect_erase (SW_BYTE_SECTOR_ADDR, (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET))){
+        return -1;
+    }
+
+    printf("Writing to Flash... ");
+    write_result = flash_write(sector_buffer, SW_BYTE_SECTOR_ADDR, SW_BYTE_SECTOR_SIZE);
+    if (write_result != 0) {
+        flash_perror (write_result);
+        return -1;
+    }
+    else{
+        printf("done\n");
+        printf("Software configuration byte is now: 0x%02x\n",
+                *((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET)));
+    }
+
+    return 0;
+}
+
+#define ONE_SECOND 1000000
+
+int do_pause(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+    int pause_time;
+    unsigned int delay_time;
+    int break_loop = 0;
+
+    /* display value if no argument */
+    if(argc < 2){
+        pause_time = 1;
+    }
+
+    else if(argc > 2){
+        printf("Too many arguments\n");
+        return -1;
+    }
+    else{
+        pause_time = simple_strtoul(argv[1], NULL, 0);
+    }
+
+    printf("Pausing with a poll time of %d, press any key to reactivate\n", pause_time);
+    delay_time = pause_time * ONE_SECOND;
+    while(break_loop == 0){
+        udelay(delay_time);
+        if(serial_tstc() != 0){
+            break_loop = 1;
+            /* eat user key presses */
+            while(serial_tstc() != 0){
+                serial_getc();
+            }
+        }
+    }
+
+    return 0;
+}
+
+int do_swreconfig(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+    printf("Triggering software reconfigure (software config byte is 0x%02x)...\n",
+           *((unsigned char *) (SW_BYTE_SECTOR_ADDR + SW_BYTE_SECTOR_OFFSET)));
+    udelay (1000);
+    *((unsigned char*)AP1000_CPLD_BASE) = 1;
+
+    return 0;
+}
+
+#define GET_DECIMAL(low_byte) ((low_byte >> 5) * 125)
+#define TEMP_BUSY_BIT   0x80
+#define TEMP_LHIGH_BIT  0x40
+#define TEMP_LLOW_BIT   0x20
+#define TEMP_EHIGH_BIT  0x10
+#define TEMP_ELOW_BIT   0x08
+#define TEMP_OPEN_BIT   0x04
+#define TEMP_ETHERM_BIT 0x02
+#define TEMP_LTHERM_BIT 0x01
+
+int do_temp_sensor(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+    char cmd;
+    int ret_val = 0;
+    unsigned char temp_byte;
+    int temp;
+    int temp_low;
+    int low;
+    int low_low;
+    int high;
+    int high_low;
+    int therm;
+    unsigned char user_data[4] = { 0 };
+    int user_data_count = 0;
+    int ii;
+
+    if(argc > 1){
+        cmd = argv[1][0];
+    }
+    else{
+        cmd = 's'; /* default to status */
+    }
+
+    user_data_count = argc - 2;
+    for(ii = 0;ii < user_data_count;ii++){
+        user_data[ii] = simple_strtoul(argv[2 + ii], NULL, 0);
+    }
+    switch (cmd){
+        case 's':{
+
+            if(I2CAccess(0x2, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            printf("Status    : 0x%02x  ", temp_byte);
+            if(temp_byte & TEMP_BUSY_BIT){
+                printf("BUSY ");
+            }
+
+            if(temp_byte & TEMP_LHIGH_BIT){
+                printf("LHIGH ");
+            }
+
+            if(temp_byte & TEMP_LLOW_BIT){
+                printf("LLOW ");
+            }
+
+            if(temp_byte & TEMP_EHIGH_BIT){
+                printf("EHIGH ");
+            }
+
+            if(temp_byte & TEMP_ELOW_BIT){
+                printf("ELOW ");
+            }
+
+            if(temp_byte & TEMP_OPEN_BIT){
+                printf("OPEN ");
+            }
+
+            if(temp_byte & TEMP_ETHERM_BIT){
+                printf("ETHERM ");
+            }
+
+            if(temp_byte & TEMP_LTHERM_BIT){
+                printf("LTHERM");
+            }
+            printf("\n");
+
+            if(I2CAccess(0x3, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            printf("Config    : 0x%02x  ", temp_byte);
+
+            if(I2CAccess(0x4, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                printf("\n");
+                goto fail;
+            }
+            printf("Conversion: 0x%02x\n", temp_byte);
+            if(I2CAccess(0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            printf("Cons Alert: 0x%02x  ", temp_byte);
+
+            if(I2CAccess(0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                printf("\n");
+                goto fail;
+            }
+            printf("Therm Hyst: %d\n", temp_byte);
+
+            if(I2CAccess(0x0, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            temp = temp_byte;
+            if(I2CAccess(0x6, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            low = temp_byte;
+            if(I2CAccess(0x5, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            high = temp_byte;
+            if(I2CAccess(0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            therm = temp_byte;
+            printf("Local Temp: %2d     Low: %2d     High: %2d     THERM: %2d\n", temp, low, high, therm);
+
+            if(I2CAccess(0x1, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            temp = temp_byte;
+            if(I2CAccess(0x10, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            temp_low = temp_byte;
+            if(I2CAccess(0x8, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            low = temp_byte;
+            if(I2CAccess(0x14, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            low_low = temp_byte;
+            if(I2CAccess(0x7, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            high = temp_byte;
+            if(I2CAccess(0x13, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            high_low = temp_byte;
+            if(I2CAccess(0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            therm = temp_byte;
+            if(I2CAccess(0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &temp_byte, I2C_READ) != 0){
+                goto fail;
+            }
+            printf("Ext Temp  : %2d.%03d Low: %2d.%03d High: %2d.%03d THERM: %2d Offset: %2d\n", temp, GET_DECIMAL(temp_low), low, GET_DECIMAL(low_low), high, GET_DECIMAL(high_low), therm, temp_byte);
+            break;
+        }
+        case 'l':{ /* alter local limits : low, high, therm */
+            if(argc < 3){
+                goto usage;
+            }
+
+            /* low */
+            if(I2CAccess(0xC, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
+                goto fail;
+            }
+
+            if(user_data_count > 1){
+                /* high */
+                if(I2CAccess(0xB, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
+                    goto fail;
+                }
+            }
+
+            if(user_data_count > 2){
+                /* therm */
+                if(I2CAccess(0x20, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
+                    goto fail;
+                }
+            }
+            break;
+        }
+        case 'e':{ /* alter external limits: low, high, therm, offset */
+            if(argc < 3){
+                goto usage;
+            }
+
+            /* low */
+            if(I2CAccess(0xE, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
+                goto fail;
+            }
+
+            if(user_data_count > 1){
+                /* high */
+                if(I2CAccess(0xD, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
+                    goto fail;
+                }
+            }
+
+            if(user_data_count > 2){
+                /* therm */
+                if(I2CAccess(0x19, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
+                    goto fail;
+                }
+            }
+
+            if(user_data_count > 3){
+                /* offset */
+                if(I2CAccess(0x11, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[3], I2C_WRITE) != 0){
+                    goto fail;
+                }
+            }
+            break;
+        }
+        case 'c':{ /* alter config settings: config, conv, cons alert, therm hyst */
+            if(argc < 3){
+                goto usage;
+            }
+
+            /* config */
+            if(I2CAccess(0x9, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[0], I2C_WRITE) != 0){
+                goto fail;
+            }
+
+            if(user_data_count > 1){
+                /* conversion */
+                if(I2CAccess(0xA, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[1], I2C_WRITE) != 0){
+                    goto fail;
+                }
+            }
+
+            if(user_data_count > 2){
+                /* cons alert */
+                if(I2CAccess(0x22, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[2], I2C_WRITE) != 0){
+                    goto fail;
+                }
+            }
+
+            if(user_data_count > 3){
+                /* therm hyst */
+                if(I2CAccess(0x21, I2C_SENSOR_DEV, I2C_SENSOR_CHIP_SEL, &user_data[3], I2C_WRITE) != 0){
+                    goto fail;
+                }
+            }
+            break;
+        }
+        default:{
+            goto usage;
+        }
+    }
+
+    goto done;
+ fail:
+    printf("Access to sensor failed\n");
+    ret_val = -1;
+    goto done;
+ usage:
+    printf ("Usage:\n%s\n", cmdtp->help);
+
+ done:
+     return ret_val;
+}
+
+U_BOOT_CMD(
+    temp,    6,    0,    do_temp_sensor,
+    "temp    - interact with the temperature sensor\n",
+    "temp [s]\n"
+    "        - Show status.\n"
+    "temp l LOW [HIGH] [THERM]\n"
+    "        - Set local limits.\n"
+    "temp e LOW [HIGH] [THERM] [OFFSET]\n"
+    "        - Set external limits.\n"
+    "temp c CONFIG [CONVERSION] [CONS. ALERT] [THERM HYST]\n"
+    "        - Set config options.\n"
+    "\n"
+    "All values can be decimal or hex (hex preceded with 0x).\n"
+    "Only whole numbers are supported for external limits.\n"
+);
+
+#if 0
+U_BOOT_CMD(
+    loadace,    2,    0,     do_loadace,
+    "loadace - load fpga configuration from System ACE compact flash\n",
+    "N\n"
+    "    - Load configuration N (0-7) from System ACE compact flash\n"
+    "loadace\n"
+    "    - loads default configuration\n"
+);
+#endif
+
+U_BOOT_CMD(
+    swconfig,    2,    0,     do_swconfigbyte,
+    "swconfig- display or modify the software configuration byte\n",
+    "N [ADDRESS]\n"
+    "    - set software configuration byte to N, optionally use ADDRESS as\n"
+    "      location of buffer for flash copy\n"
+    "swconfig\n"
+    "    - display software configuration byte\n"
+);
+
+U_BOOT_CMD(
+    pause,    2,    0,     do_pause,
+    "pause   - sleep processor until any key is pressed with poll time of N seconds\n",
+    "N\n"
+    "    - sleep processor until any key is pressed with poll time of N seconds\n"
+    "pause\n"
+    "    - sleep processor until any key is pressed with poll time of 1 second\n"
+);
+
+U_BOOT_CMD(
+    swrecon,    1,    0,     do_swreconfig,
+    "swrecon - trigger a board reconfigure to the software selected configuration\n",
+    "\n"
+    "    - trigger a board reconfigure to the software selected configuration\n"
+);
+
diff --git a/board/amirix/ap1000/ap1000.h b/board/amirix/ap1000/ap1000.h
new file mode 100644
index 0000000..c93736f
--- /dev/null
+++ b/board/amirix/ap1000/ap1000.h
@@ -0,0 +1,173 @@
+/*
+ * ap1000.h: AP1000 (e.g. AP1070, AP1100) board specific definitions and functions that are needed globally
+ *
+ * Author : James MacAulay
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire
+ * program is licensed under the GPL.
+ *
+ */
+
+#ifndef __AP1000_H
+#define __AP1000_H
+
+/*
+ *  Revision Register stuff
+ */
+#define AP1xx_FPGA_REV_ADDR 0x29000000
+
+#define AP1xx_PLATFORM_MASK      0xFF000000
+#define AP100_BASELINE_PLATFORM  0x01000000
+#define AP1xx_QUADGE_PLATFORM    0x02000000
+#define AP1xx_MGT_REF_PLATFORM   0x03000000
+#define AP1xx_STANDARD_PLATFORM  0x04000000
+#define AP1xx_DUAL_PLATFORM      0x05000000
+#define AP1xx_BASE_SRAM_PLATFORM 0x06000000
+
+#define AP1000_BASELINE_PLATFORM 0x21000000
+
+#define AP1xx_TESTPLATFORM_MASK         0xC0000000
+#define AP1xx_PCI_PCB_TESTPLATFORM      0xC0000000
+#define AP1xx_DUAL_GE_MEZZ_TESTPLATFORM 0xC1000000
+#define AP1xx_SFP_MEZZ_TESTPLATFORM     0xC2000000
+
+#define AP1000_PCI_PCB_TESTPLATFORM      0xC3000000
+
+#define AP1xx_TARGET_MASK  0x00FF0000
+#define AP1xx_AP107_TARGET 0x00010000
+#define AP1xx_AP120_TARGET 0x00020000
+#define AP1xx_AP130_TARGET 0x00030000
+#define AP1xx_AP1070_TARGET 0x00040000
+#define AP1xx_AP1100_TARGET 0x00050000
+
+#define AP1xx_UNKNOWN_STR "Unknown"
+
+#define AP1xx_PLATFORM_STR           " Platform"
+#define AP1xx_BASELINE_PLATFORM_STR  "Baseline"
+#define AP1xx_QUADGE_PLATFORM_STR    "Quad GE"
+#define AP1xx_MGT_REF_PLATFORM_STR   "MGT Reference"
+#define AP1xx_STANDARD_PLATFORM_STR  "Standard"
+#define AP1xx_DUAL_PLATFORM_STR      "Dual"
+#define AP1xx_BASE_SRAM_PLATFORM_STR "Baseline with SRAM"
+
+#define AP1xx_TESTPLATFORM_STR              " Test Platform"
+#define AP1xx_PCI_PCB_TESTPLATFORM_STR      "Base"
+#define AP1xx_DUAL_GE_MEZZ_TESTPLATFORM_STR "Dual GE Mezzanine"
+#define AP1xx_SFP_MEZZ_TESTPLATFORM_STR     "SFP Mezzanine"
+
+#define AP1xx_TARGET_STR       " Board"
+#define AP1xx_AP107_TARGET_STR "AP107"
+#define AP1xx_AP120_TARGET_STR "AP120"
+#define AP1xx_AP130_TARGET_STR "AP130"
+
+#define AP1xx_AP1070_TARGET_STR "AP1070"
+#define AP1xx_AP1100_TARGET_STR "AP1100"
+
+/*
+ *  Flash Stuff
+ */
+#define AP1xx_PROGRAM_FLASH_INDEX   0
+#define AP1xx_CONFIG_FLASH_INDEX    1
+
+/*
+ *  System Ace Stuff
+ */
+#define AP1000_SYSACE_REGBASE  0x28000000
+
+#define SYSACE_STATREG0 0x04 // 7:0
+#define SYSACE_STATREG1 0x05 // 15:8
+#define SYSACE_STATREG2 0x06 // 23:16
+#define SYSACE_STATREG3 0x07 // 31:24
+
+#define SYSACE_ERRREG0 0x08 // 7:0
+#define SYSACE_ERRREG1 0x09 // 15:8
+#define SYSACE_ERRREG2 0x0a // 23:16
+#define SYSACE_ERRREG3 0x0b // 31:24
+
+#define SYSACE_CTRLREG0 0x18 // 7:0
+#define SYSACE_CTRLREG1 0x19 // 15:8
+#define SYSACE_CTRLREG2 0x1A // 23:16
+#define SYSACE_CTRLREG3 0x1B // 31:24
+
+/*
+ *  Software reconfig thing
+ */
+#define SW_BYTE_SECTOR_ADDR     0x24FE0000
+#define SW_BYTE_SECTOR_OFFSET   0x0001FFFF
+#define SW_BYTE_SECTOR_SIZE     0x00020000
+#define SW_BYTE_MASK            0x00000003
+
+#define DEFAULT_TEMP_ADDR       0x00100000
+
+#define AP1000_CPLD_BASE       0x26000000
+
+/* PowerSpan II Stuff */
+#define PSII_SYNC() asm("eieio")
+#define PSPAN_BASEADDR 0x30000000
+#define EEPROM_DEFAULT { 0x01,       /* Byte 0 - Long Load = 0x02, short = 01, use 0xff for try no load */  \
+                        0x0,0x0,0x0, /* Bytes 1 - 3 Power span reserved */ \
+                        0x0,         /* Byte 4 - Powerspan reserved  - start of short load */ \
+                        0x0F,        /* Byte 5 - Enable PCI 1 & 2 as Bus masters and Memory targets. */ \
+                        0x0E,        /* Byte 6 - PCI 1 Target image prefetch - on for image 0,1,2, off for i20 & 3. */ \
+                        0x00, 0x00,  /* Byte 7,8 - PCI-1 Subsystem ID - */ \
+                        0x00, 0x00,  /* Byte 9,10 - PCI-1 Subsystem Vendor Id -  */ \
+                        0x00,        /* Byte 11 - No PCI interrupt generation on PCI-1 PCI-2 int A */ \
+                        0x1F,        /* Byte 12 - PCI-1 enable bridge registers, all target images */ \
+                        0xBA,        /* Byte 13 - Target 0 image 128 Meg(Ram), Target 1 image 64 Meg. (config Flash/CPLD )*/ \
+                        0xA0,        /* Byte 14 - Target 2 image 64 Meg(program Flash), target 3 64k. */ \
+                        0x00,        /* Byte 15 - Vital Product Data Disabled. */ \
+                        0x88,        /* Byte 16 - PCI arbiter config complete, all requests routed through PCI-1, Unlock PCI-1  */ \
+                        0x40,        /* Byte 17 - Interrupt direction control - PCI-1 Int A out, everything else in. */ \
+                        0x00,        /* Byte 18 - I2O disabled */ \
+                        0x00,        /* Byte 19 - PCI-2 Target image prefetch - off for all images. */ \
+                        0x00,0x00,   /* Bytes 20,21 - PCI 2 Subsystem Id */ \
+                        0x00,0x00,   /* Bytes 22,23 - PCI 2 Subsystem Vendor id */ \
+                        0x0C,        /* Byte 24 - PCI-2 BAR enables, target image 0, & 1 */ \
+                        0xBB,        /* Byte 25 - PCI-2 target 0 - 128 Meg(Ram), target 1  - 128 Meg (program/config flash) */ \
+                        0x00,        /* Byte 26 - PCI-2 target 2 & 3 unused. */ \
+                        0x00,0x00,0x00,0x00,0x00, /* Bytes 27,28,29,30, 31 - Reserved */ \
+                        /* Long Load Information */ \
+                        0x82,0x60,   /* Bytes 32,33 - PCI-1 Device ID - Powerspan II */ \
+                        0x10,0xE3,   /* Bytes 24,35 - PCI-1 Vendor ID - Tundra */ \
+                        0x06,        /* Byte 36 - PCI-1 Class Base - Bridge device. */ \
+                        0x80,        /* Byte 37 - PCI-1 Class sub class - Other bridge. */ \
+                        0x00,        /* Byte 38 - PCI-1 Class programing interface - Other bridge */ \
+                        0x01,        /* Byte 39 - Power span revision 1. */ \
+                        0x6E,        /* Byte 40 - PB SI0 enabled, translation enabled, decode enabled, 64 Meg */ \
+                        0x40,        /* Byte 41 - PB SI0 memory command mode, PCI-1 dest */ \
+                        0x22,        /* Byte 42 - Prefetch discard after read, PCI-little endian conversion, 32 byte prefetch */ \
+                        0x00,0x00,   /* Bytes 43, 44 - Translation address for SI0, set to zero for now. */ \
+                        0x0E,        /* Byte 45 - Translation address (0) and PB bus master enables - all. */ \
+                        0x2c,00,00,  /* Bytes 46,47,48 - PB SI0 processor base address - 0x2C000000 */ \
+                        0x30,00,00,  /* Bytes 49,50,51 - PB Address for Powerspan registers - 0x30000000, big Endian */ \
+                        0x82,0x60,   /* Bytes 52, 53 - PCI-2 Device ID - Powerspan II */ \
+                        0x10,0xE3,   /* Bytes 54,55 - PCI 2 Vendor Id - Tundra */ \
+                        0x06,        /* Byte 56 - PCI-2 Class Base - Bridge device */ \
+                        0x80,        /* Byte 57 - PCI-2 Class sub class - Other Bridge. */ \
+                        0x00,        /* Byte 58 - PCI-2 class programming interface - Other bridge */ \
+                        0x01,        /* Byte 59 - PCI-2 class revision  1 */ \
+                        0x00,0x00,0x00,0x00 }; /* Bytes 60,61, 62, 63 - Powerspan reserved */
+
+
+#define EEPROM_LENGTH   64  /* Long Load */
+
+#define I2C_SENSOR_DEV      0x9
+#define I2C_SENSOR_CHIP_SEL 0x4
+
+/*
+ *  Board Functions
+ */
+void set_eat_machine_checks(int a_flag);
+int get_eat_machine_checks(void);
+unsigned int get_platform(void);
+unsigned int get_device(void);
+void* memcpyb(void * dest,const void *src,size_t count);
+int process_bootflag(ulong bootflag);
+void user_led_on(void);
+void user_led_off(void);
+
+#endif	/* __COMMON_H_ */
diff --git a/board/amirix/ap1000/config.mk b/board/amirix/ap1000/config.mk
new file mode 100644
index 0000000..c09783a
--- /dev/null
+++ b/board/amirix/ap1000/config.mk
@@ -0,0 +1,27 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+# Start at bottom of RAM, but at an aliased address so that it looks
+# like it's not in RAM.  This is a bit of voodoo to allow it to be
+# run from RAM instead of Flash.
+TEXT_BASE = 0x08000000
diff --git a/board/amirix/ap1000/flash.c b/board/amirix/ap1000/flash.c
new file mode 100644
index 0000000..f07edf0
--- /dev/null
+++ b/board/amirix/ap1000/flash.c
@@ -0,0 +1,853 @@
+/**
+ * @file flash.c
+ */
+
+/*
+ * (C) Copyright 2003
+ * AMIRIX Systems Inc.
+ *
+ * Originated from ppcboot-2.0.0/board/esd/cpci440/strataflash.c
+ *
+ * (C) Copyright 2002
+ * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+
+#undef  DEBUG_FLASH
+/*
+ * This file implements a Common Flash Interface (CFI) driver for ppcboot.
+ * The width of the port and the width of the chips are determined at initialization.
+ * These widths are used to calculate the address for access CFI data structures.
+ * It has been tested on an Intel Strataflash implementation.
+ *
+ * References
+ * JEDEC Standard JESD68 - Common Flash Interface (CFI)
+ * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
+ * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
+ * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
+ *
+ * TODO
+ * Use Primary Extended Query table (PRI) and Alternate Algorithm Query Table (ALT) to determine if protection is available
+ * Add support for other command sets Use the PRI and ALT to determine command set
+ * Verify erase and program timeouts.
+ */
+
+#define FLASH_CMD_CFI           0x98
+#define FLASH_CMD_READ_ID       0x90
+#define FLASH_CMD_RESET         0xff
+#define FLASH_CMD_BLOCK_ERASE       0x20
+#define FLASH_CMD_ERASE_CONFIRM     0xD0
+#define FLASH_CMD_WRITE         0x40
+#define FLASH_CMD_PROTECT       0x60
+#define FLASH_CMD_PROTECT_SET       0x01
+#define FLASH_CMD_PROTECT_CLEAR     0xD0
+#define FLASH_CMD_CLEAR_STATUS      0x50
+#define FLASH_CMD_WRITE_TO_BUFFER       0xE8
+#define FLASH_CMD_WRITE_BUFFER_CONFIRM  0xD0
+
+#define FLASH_STATUS_DONE       0x80
+#define FLASH_STATUS_ESS        0x40
+#define FLASH_STATUS_ECLBS      0x20
+#define FLASH_STATUS_PSLBS      0x10
+#define FLASH_STATUS_VPENS      0x08
+#define FLASH_STATUS_PSS        0x04
+#define FLASH_STATUS_DPS        0x02
+#define FLASH_STATUS_R          0x01
+#define FLASH_STATUS_PROTECT        0x01
+
+#define FLASH_OFFSET_CFI        0x55
+#define FLASH_OFFSET_CFI_RESP       0x10
+#define FLASH_OFFSET_WTOUT      0x1F
+#define FLASH_OFFSET_WBTOUT             0x20
+#define FLASH_OFFSET_ETOUT      0x21
+#define FLASH_OFFSET_CETOUT             0x22
+#define FLASH_OFFSET_WMAX_TOUT      0x23
+#define FLASH_OFFSET_WBMAX_TOUT         0x24
+#define FLASH_OFFSET_EMAX_TOUT      0x25
+#define FLASH_OFFSET_CEMAX_TOUT         0x26
+#define FLASH_OFFSET_SIZE       0x27
+#define FLASH_OFFSET_INTERFACE          0x28
+#define FLASH_OFFSET_BUFFER_SIZE        0x2A
+#define FLASH_OFFSET_NUM_ERASE_REGIONS  0x2C
+#define FLASH_OFFSET_ERASE_REGIONS  0x2D
+#define FLASH_OFFSET_PROTECT        0x02
+#define FLASH_OFFSET_USER_PROTECTION    0x85
+#define FLASH_OFFSET_INTEL_PROTECTION   0x81
+
+
+#define FLASH_MAN_CFI           0x01000000
+
+
+
+
+typedef union {
+    unsigned char c;
+    unsigned short w;
+    unsigned long l;
+} cfiword_t;
+
+typedef union {
+    unsigned char * cp;
+    unsigned short *wp;
+    unsigned long *lp;
+} cfiptr_t;
+
+#define NUM_ERASE_REGIONS 4
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips    */
+
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+
+
+
+static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c);
+static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf);
+static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd);
+static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd);
+static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd);
+static int flash_detect_cfi(flash_info_t * info);
+static ulong flash_get_size (ulong base, int banknum);
+static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword);
+static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt);
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len);
+#endif
+/*-----------------------------------------------------------------------
+ * create an address based on the offset and the port width
+ */
+uchar * flash_make_addr(flash_info_t * info, int sect, int offset)
+{
+    return ((uchar *)(info->start[sect] + (offset * info->chipwidth)));
+}
+/*-----------------------------------------------------------------------
+ * read a character at a port width address
+ */
+uchar flash_read_uchar(flash_info_t * info, uchar offset)
+{
+    if (info->portwidth == FLASH_CFI_8BIT) {
+        volatile uchar *cp;
+        uchar c;
+        cp = flash_make_addr(info, 0, offset);
+        c = *cp;
+#ifdef DEBUG_FLASH
+        printf("flash_read_uchar offset=%04x ptr=%08x c=%02x\n",
+                        offset, (unsigned int)cp, c);
+#endif
+        return (c);
+
+    } else if (info->portwidth == FLASH_CFI_16BIT) {
+        volatile ushort *sp;
+        ushort s;
+        uchar c;
+        sp = (ushort*)flash_make_addr(info, 0, offset);
+        s = *sp;
+        c = (uchar)s;
+#ifdef DEBUG_FLASH
+        printf("flash_read_uchar offset=%04x ptr=%08x s=%04x c=%02x\n",
+                       offset, (unsigned int)sp, s, c);
+#endif
+        return (c);
+
+    }
+
+    return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * read a short word by swapping for ppc format.
+ */
+ushort flash_read_ushort(flash_info_t * info, int sect,  uchar offset)
+{
+    if (info->portwidth == FLASH_CFI_8BIT) {
+        volatile uchar *cp;
+        uchar c0, c1;
+        ushort s;
+        cp = flash_make_addr(info, 0, offset);
+        c1 = cp[2];
+        c0 = cp[0];
+        s = c1<<8 | c0;
+#ifdef DEBUG_FLASH
+        printf("flash_read_ushort offset=%04x ptr=%08x c1=%02x c0=%02x s=%04x\n",
+                        offset, (unsigned int)cp, c1, c0, s);
+#endif
+        return (s);
+
+    } else if (info->portwidth == FLASH_CFI_16BIT) {
+        volatile ushort *sp;
+        ushort s;
+        uchar c0, c1;
+        sp = (ushort*)flash_make_addr(info, 0, offset);
+        s = *sp;
+        c1 = (uchar)sp[1];
+        c0 = (uchar)sp[0];
+        s = c1<<8 | c0;
+#ifdef DEBUG_FLASH
+        printf("flash_read_ushort offset=%04x ptr=%08x c1=%02x c0=%02x s=%04x\n",
+                        offset, (unsigned int)sp, c1, c0, s);
+#endif
+        return (s);
+
+    }
+
+    return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * read a long word by picking the least significant byte of each maiximum
+ * port size word. Swap for ppc format.
+ */
+ulong flash_read_long(flash_info_t * info, int sect,  uchar offset)
+{
+    if (info->portwidth == FLASH_CFI_8BIT) {
+        volatile uchar *cp;
+        uchar c0, c1, c2, c3;
+        ulong l;
+        cp = flash_make_addr(info, 0, offset);
+        c3 = cp[6];
+        c2 = cp[4];
+        c1 = cp[2];
+        c0 = cp[0];
+        l = c3<<24 | c2<<16 | c1<<8 | c0;
+#ifdef DEBUG_FLASH
+        printf("flash_read_long offset=%04x ptr=%08x c3=%02x c2=%02x c1=%02x c0=%02x l=%08x\n",
+                        offset, (unsigned int)cp, c3, c2, c1, c0, l);
+#endif
+        return (l);
+
+    } else if (info->portwidth == FLASH_CFI_16BIT) {
+        volatile ushort *sp;
+        uchar c0, c1, c2, c3;
+        ulong l;
+        sp = (ushort*)flash_make_addr(info, 0, offset);
+        c3 = (uchar)sp[3];
+        c2 = (uchar)sp[2];
+        c1 = (uchar)sp[1];
+        c0 = (uchar)sp[0];
+        l = c3<<24 | c2<<16 | c1<<8 | c0;
+#ifdef DEBUG_FLASH
+        printf("flash_read_long offset=%04x ptr=%08x c3=%02x c2=%02x c1=%02x c0=%02x l=%08x\n",
+                        offset, (unsigned int)sp, c3, c2, c1, c0, l);
+#endif
+        return (l);
+
+    }
+
+    return 0;
+}
+
+/*-----------------------------------------------------------------------
+ */
+unsigned long flash_init (void)
+{
+    unsigned long size;
+
+    size = 0;
+
+    flash_info[0].flash_id = FLASH_UNKNOWN;
+    flash_info[0].portwidth = FLASH_CFI_16BIT;
+    flash_info[0].chipwidth = FLASH_CFI_16BIT;
+    size += flash_info[0].size = flash_get_size(CFG_PROGFLASH_BASE, 0);
+    if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+        printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", 1,
+        flash_info[0].size, flash_info[0].size<<20);
+        };
+
+    flash_info[1].flash_id = FLASH_UNKNOWN;
+    flash_info[1].portwidth = FLASH_CFI_8BIT;
+    flash_info[1].chipwidth = FLASH_CFI_16BIT;
+    size += flash_info[1].size = flash_get_size(CFG_CONFFLASH_BASE, 1);
+    if (flash_info[1].flash_id == FLASH_UNKNOWN) {
+        printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", 2,
+        flash_info[1].size, flash_info[1].size<<20);
+    };
+
+    return (size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+    int rcode = 0;
+    int prot;
+    int sect;
+
+    if( info->flash_id != FLASH_MAN_CFI) {
+        printf ("Can't erase unknown flash type - aborted\n");
+        return 1;
+    }
+    if ((s_first < 0) || (s_first > s_last)) {
+        printf ("- no sectors to erase\n");
+        return 1;
+    }
+
+    prot = 0;
+    for (sect=s_first; sect<=s_last; ++sect) {
+        if (info->protect[sect]) {
+            prot++;
+        }
+    }
+    if (prot) {
+        printf ("- Warning: %d protected sectors will not be erased!\n",
+            prot);
+    } else {
+        printf ("\n");
+    }
+
+
+    for (sect = s_first; sect<=s_last; sect++) {
+        if (info->protect[sect] == 0) { /* not protected */
+            flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS);
+            flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE);
+            flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
+
+            if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) {
+                rcode = 1;
+            } else
+                printf(".");
+        }
+    }
+    printf (" done\n");
+    return rcode;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+    int i;
+
+    if (info->flash_id != FLASH_MAN_CFI) {
+        printf ("missing or unknown FLASH type\n");
+        return;
+    }
+
+    printf("CFI conformant FLASH (x%d device in x%d mode)",
+           (info->chipwidth  << 3 ), (info->portwidth  << 3 ));
+    printf ("  Size: %ld MB in %d Sectors\n",
+        info->size >> 20, info->sector_count);
+    printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
+           info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);
+
+    printf ("  Sector Start Addresses:");
+    for (i=0; i<info->sector_count; ++i) {
+        if ((i % 5) == 0)
+            printf ("\n");
+        printf (" %08lX%5s",
+            info->start[i],
+            info->protect[i] ? " (RO)" : " "
+            );
+    }
+    printf ("\n");
+    return;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    ulong wp;
+    ulong cp;
+    int aln;
+    cfiword_t cword;
+    int i, rc;
+
+    /* get lower aligned address */
+    wp = (addr & ~(info->portwidth - 1));
+
+    /* handle unaligned start */
+    if((aln = addr - wp) != 0) {
+        cword.l = 0;
+        cp = wp;
+        for(i=0;i<aln; ++i, ++cp)
+            flash_add_byte(info, &cword, (*(uchar *)cp));
+
+        for(; (i< info->portwidth) && (cnt > 0) ; i++) {
+            flash_add_byte(info, &cword, *src++);
+            cnt--;
+            cp++;
+        }
+        for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
+            flash_add_byte(info, &cword, (*(uchar *)cp));
+        if((rc = flash_write_cfiword(info, wp, cword)) != 0)
+            return rc;
+        wp = cp;
+    }
+
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+    while(cnt >= info->portwidth) {
+        i = info->buffer_size > cnt? cnt: info->buffer_size;
+        if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK)
+            return rc;
+        wp += i;
+        src += i;
+        cnt -=i;
+    }
+#else
+    /* handle the aligned part */
+    while(cnt >= info->portwidth) {
+        cword.l = 0;
+        for(i = 0; i < info->portwidth; i++) {
+            flash_add_byte(info, &cword, *src++);
+        }
+        if((rc = flash_write_cfiword(info, wp, cword)) != 0)
+            return rc;
+        wp += info->portwidth;
+        cnt -= info->portwidth;
+    }
+#endif /* CFG_FLASH_USE_BUFFER_WRITE */
+    if (cnt == 0) {
+        return (0);
+    }
+
+    /*
+     * handle unaligned tail bytes
+     */
+    cword.l = 0;
+    for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) {
+        flash_add_byte(info, &cword, *src++);
+        --cnt;
+    }
+    for (; i<info->portwidth; ++i, ++cp) {
+        flash_add_byte(info, & cword, (*(uchar *)cp));
+    }
+
+    return flash_write_cfiword(info, wp, cword);
+}
+
+/*-----------------------------------------------------------------------
+ */
+int flash_real_protect(flash_info_t *info, long sector, int prot)
+{
+    int retcode = 0;
+
+    flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+    flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
+    if(prot)
+        flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET);
+    else
+        flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
+
+    if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout,
+                     prot?"protect":"unprotect")) == 0) {
+
+        info->protect[sector] = prot;
+        /* Intel's unprotect unprotects all locking */
+        if(prot == 0) {
+            int i;
+            for(i = 0 ; i<info->sector_count; i++) {
+                if(info->protect[i])
+                    flash_real_protect(info, i, 1);
+            }
+        }
+    }
+
+    return retcode;
+}
+/*-----------------------------------------------------------------------
+ *  wait for XSR.7 to be set. Time out with an error if it does not.
+ *  This routine does not set the flash to read-array mode.
+ */
+static int flash_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
+{
+    ulong start;
+
+    /* Wait for command completion */
+    start = get_timer (0);
+    while(!flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
+        if (get_timer(start) > info->erase_blk_tout) {
+            printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]);
+            flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
+            return ERR_TIMOUT;
+        }
+    }
+    return ERR_OK;
+}
+/*-----------------------------------------------------------------------
+ * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
+ * This routine sets the flash to read-array mode.
+ */
+static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
+{
+    int retcode;
+    retcode = flash_status_check(info, sector, tout, prompt);
+    if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) {
+        retcode = ERR_INVAL;
+        printf("Flash %s error at address %lx\n", prompt,info->start[sector]);
+        if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){
+            printf("Command Sequence Error.\n");
+        } else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){
+            printf("Block Erase Error.\n");
+                retcode = ERR_NOT_ERASED;
+        } else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) {
+            printf("Locking Error\n");
+        }
+        if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){
+            printf("Block locked.\n");
+            retcode = ERR_PROTECTED;
+        }
+        if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS))
+            printf("Vpp Low Error.\n");
+    }
+    flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
+    return retcode;
+}
+/*-----------------------------------------------------------------------
+ */
+static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c)
+{
+    switch(info->portwidth) {
+    case FLASH_CFI_8BIT:
+        cword->c = c;
+        break;
+    case FLASH_CFI_16BIT:
+        cword->w = (cword->w << 8) | c;
+        break;
+    case FLASH_CFI_32BIT:
+        cword->l = (cword->l << 8) | c;
+    }
+}
+
+
+/*-----------------------------------------------------------------------
+ * make a proper sized command based on the port and chip widths
+ */
+static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf)
+{
+    //int i;
+    uchar *cp = (uchar *)cmdbuf;
+    // for(i=0; i< info->portwidth; i++)
+    //  *cp++ = ((i+1) % info->chipwidth) ? '\0':cmd;
+        if (info->portwidth == FLASH_CFI_8BIT && info->chipwidth == FLASH_CFI_16BIT) {
+        cp[0] = cmd;
+        } else if (info->portwidth == FLASH_CFI_16BIT && info->chipwidth == FLASH_CFI_16BIT) {
+        cp[0] = '\0';
+        cp[1] = cmd;
+    };
+}
+
+/*
+ * Write a proper sized command to the correct address
+ */
+static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd)
+{
+
+    volatile cfiptr_t addr;
+    cfiword_t cword;
+    addr.cp = flash_make_addr(info, sect, offset);
+    flash_make_cmd(info, cmd, &cword);
+    switch(info->portwidth) {
+    case FLASH_CFI_8BIT:
+        *addr.cp = cword.c;
+        break;
+    case FLASH_CFI_16BIT:
+        *addr.wp = cword.w;
+        break;
+    case FLASH_CFI_32BIT:
+        *addr.lp = cword.l;
+        break;
+    }
+}
+
+/*-----------------------------------------------------------------------
+ */
+static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd)
+{
+    cfiptr_t cptr;
+    cfiword_t cword;
+    int retval;
+    cptr.cp = flash_make_addr(info, sect, offset);
+    flash_make_cmd(info, cmd, &cword);
+    switch(info->portwidth) {
+    case FLASH_CFI_8BIT:
+        retval = (cptr.cp[0] == cword.c);
+        break;
+    case FLASH_CFI_16BIT:
+        retval = (cptr.wp[0] == cword.w);
+        break;
+    case FLASH_CFI_32BIT:
+        retval = (cptr.lp[0] == cword.l);
+        break;
+    default:
+        retval = 0;
+        break;
+    }
+    return retval;
+}
+/*-----------------------------------------------------------------------
+ */
+static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd)
+{
+    cfiptr_t cptr;
+    cfiword_t cword;
+    int retval;
+    cptr.cp = flash_make_addr(info, sect, offset);
+    flash_make_cmd(info, cmd, &cword);
+    switch(info->portwidth) {
+    case FLASH_CFI_8BIT:
+        retval = ((cptr.cp[0] & cword.c) == cword.c);
+        break;
+    case FLASH_CFI_16BIT:
+        retval = ((cptr.wp[0] & cword.w) == cword.w);
+        break;
+    case FLASH_CFI_32BIT:
+        retval = ((cptr.lp[0] & cword.l) == cword.l);
+        break;
+    default:
+        retval = 0;
+        break;
+    }
+    return retval;
+}
+
+/*-----------------------------------------------------------------------
+ * detect if flash is compatible with the Common Flash Interface (CFI)
+ * http://www.jedec.org/download/search/jesd68.pdf
+ *
+*/
+static int flash_detect_cfi(flash_info_t * info)
+{
+
+#if 0
+    for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_32BIT;
+        info->portwidth <<= 1) {
+        for(info->chipwidth =FLASH_CFI_BY8;
+            info->chipwidth <= info->portwidth;
+            info->chipwidth <<= 1) {
+            flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+            flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
+            if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
+               flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
+               flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y'))
+                return 1;
+        }
+    }
+#endif
+    flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+    flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
+    if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
+       flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
+       flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+        return 1;
+    } else {
+        return 0;
+    };
+}
+/*
+ * The following code cannot be run from FLASH!
+ *
+ */
+static ulong flash_get_size (ulong base, int banknum)
+{
+    flash_info_t * info = &flash_info[banknum];
+    int i, j;
+    int sect_cnt;
+    unsigned long sector;
+    unsigned long tmp;
+    int size_ratio;
+    uchar num_erase_regions;
+    int  erase_region_size;
+    int  erase_region_count;
+
+    info->start[0] = base;
+
+    if(flash_detect_cfi(info)){
+#ifdef DEBUG_FLASH
+        printf("portwidth=%d chipwidth=%d\n", info->portwidth, info->chipwidth); /* test-only */
+#endif
+        size_ratio = 1; // info->portwidth / info->chipwidth;
+        num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS);
+#ifdef DEBUG_FLASH
+        printf("found %d erase regions\n", num_erase_regions);
+#endif
+        sect_cnt = 0;
+        sector = base;
+        for(i = 0 ; i < num_erase_regions; i++) {
+            if(i > NUM_ERASE_REGIONS) {
+                printf("%d erase regions found, only %d used\n",
+                       num_erase_regions, NUM_ERASE_REGIONS);
+                break;
+            }
+            tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS);
+            erase_region_count = (tmp & 0xffff) +1;
+            tmp >>= 16;
+            erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128;
+            for(j = 0; j< erase_region_count; j++) {
+                info->start[sect_cnt] = sector;
+                sector += (erase_region_size * size_ratio);
+                info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT);
+                sect_cnt++;
+            }
+        }
+
+        info->sector_count = sect_cnt;
+        /* multiply the size by the number of chips */
+        info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio;
+        info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE));
+        tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT);
+        info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT)));
+        tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT);
+        info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT)));
+        tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT);
+        info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000;
+        info->flash_id = FLASH_MAN_CFI;
+    }
+
+    flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+    return(info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword)
+{
+
+    cfiptr_t ctladdr;
+    cfiptr_t cptr;
+    int flag;
+
+    ctladdr.cp = flash_make_addr(info, 0, 0);
+    cptr.cp = (uchar *)dest;
+
+
+    /* Check if Flash is (sufficiently) erased */
+    switch(info->portwidth) {
+    case FLASH_CFI_8BIT:
+        flag = ((cptr.cp[0] & cword.c) == cword.c);
+        break;
+    case FLASH_CFI_16BIT:
+        flag = ((cptr.wp[0] & cword.w) == cword.w);
+        break;
+    case FLASH_CFI_32BIT:
+        flag = ((cptr.lp[0] & cword.l)  == cword.l);
+        break;
+    default:
+        return 2;
+    }
+    if(!flag)
+        return 2;
+
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
+    flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);
+
+    switch(info->portwidth) {
+    case FLASH_CFI_8BIT:
+        cptr.cp[0] = cword.c;
+        break;
+    case FLASH_CFI_16BIT:
+        cptr.wp[0] = cword.w;
+        break;
+    case FLASH_CFI_32BIT:
+        cptr.lp[0] = cword.l;
+        break;
+    }
+
+    /* re-enable interrupts if necessary */
+    if(flag)
+        enable_interrupts();
+
+    return flash_full_status_check(info, 0, info->write_tout, "write");
+}
+
+#ifdef CFG_FLASH_USE_BUFFER_WRITE
+
+/* loop through the sectors from the highest address
+ * when the passed address is greater or equal to the sector address
+ * we have a match
+ */
+static int find_sector(flash_info_t *info, ulong addr)
+{
+    int sector;
+    for(sector = info->sector_count - 1; sector >= 0; sector--) {
+        if(addr >= info->start[sector])
+            break;
+    }
+    return sector;
+}
+
+static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len)
+{
+
+    int sector;
+    int cnt;
+    int retcode;
+    volatile cfiptr_t src;
+    volatile cfiptr_t dst;
+
+    src.cp = cp;
+    dst.cp = (uchar *)dest;
+    sector = find_sector(info, dest);
+    flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+    flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
+    if((retcode = flash_status_check(info, sector, info->buffer_write_tout,
+                     "write to buffer")) == ERR_OK) {
+        switch(info->portwidth) {
+        case FLASH_CFI_8BIT:
+            cnt = len;
+            break;
+        case FLASH_CFI_16BIT:
+            cnt = len >> 1;
+            break;
+        case FLASH_CFI_32BIT:
+            cnt = len >> 2;
+            break;
+        default:
+            return ERR_INVAL;
+            break;
+        }
+        flash_write_cmd(info, sector, 0, (uchar)cnt-1);
+        while(cnt-- > 0) {
+            switch(info->portwidth) {
+            case FLASH_CFI_8BIT:
+                *dst.cp++ = *src.cp++;
+                break;
+            case FLASH_CFI_16BIT:
+                *dst.wp++ = *src.wp++;
+                break;
+            case FLASH_CFI_32BIT:
+                *dst.lp++ = *src.lp++;
+                break;
+            default:
+                return ERR_INVAL;
+                break;
+            }
+        }
+        flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM);
+        retcode = flash_full_status_check(info, sector, info->buffer_write_tout,
+                         "buffer write");
+    }
+    flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+    return retcode;
+}
+#endif /* CFG_USE_FLASH_BUFFER_WRITE */
diff --git a/board/amirix/ap1000/init.S b/board/amirix/ap1000/init.S
new file mode 100644
index 0000000..8c3a357
--- /dev/null
+++ b/board/amirix/ap1000/init.S
@@ -0,0 +1,34 @@
+/*
+ * init.S: Stubs for ppcboot initialization
+ *
+ * Copyright 2002 Mind NV
+ *
+ * http://www.mind.be/
+ *
+ * Author : Peter De Schrijver (p2@mind.be)
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire
+ * program is licensed under the GPL.
+ *
+ */
+
+#include <ppc4xx.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+
+     	.globl	ext_bus_cntlr_init
+ext_bus_cntlr_init:
+        blr
+
+        .globl  sdram_init
+sdram_init:
+        blr
diff --git a/board/amirix/ap1000/pci.c b/board/amirix/ap1000/pci.c
new file mode 100644
index 0000000..34cd587
--- /dev/null
+++ b/board/amirix/ap1000/pci.c
@@ -0,0 +1,346 @@
+/*
+ * (C) Copyright 2003
+ * AMIRIX Systems Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+#include <pci.h>
+
+#define PCI_MEM_82559ER_CSR_BASE    0x30200000
+#define PCI_IO_82559ER_CSR_BASE     0x40000200
+
+/** AP1100 specific values */
+#define PSII_BASE                   0x30000000    /**< PowerSpan II dual bridge local bus register address */
+#define PSII_CONFIG_ADDR            0x30000290    /**< PowerSpan II Configuration Cycle Address configuration register */
+#define PSII_CONFIG_DATA            0x30000294    /**< PowerSpan II Configuration Cycle Data register. */
+#define PSII_CONFIG_DEST_PCI2       0x01000000    /**< PowerSpan II configuration cycle destination selection, set for PCI2 bus */
+#define PSII_PCI_MEM_BASE           0x30200000    /**< Local Bus address for start of PCI memory space on PCI2 bus. */
+#define PSII_PCI_MEM_SIZE           0x1BE00000    /**< PCI Memory space about 510 Meg. */
+#define AP1000_SYS_MEM_START        0x00000000    /**< System memory starts at 0. */
+#define AP1000_SYS_MEM_SIZE         0x08000000    /**< System memory is 128 Meg. */
+
+/* static int G_verbosity_level = 1; */
+#define G_verbosity_level 1
+
+void write1(unsigned long addr, unsigned char val) {
+    volatile unsigned char* p = (volatile unsigned char*)addr;
+
+    if(G_verbosity_level > 1)
+        printf("write1: addr=%08x val=%02x\n", (unsigned int)addr, val);
+    *p = val;
+    asm("eieio");
+}
+
+unsigned char read1(unsigned long addr) {
+    unsigned char val;
+    volatile unsigned char* p = (volatile unsigned char*)addr;
+
+    if(G_verbosity_level > 1)
+        printf("read1: addr=%08x ", (unsigned int)addr);
+    val = *p;
+    asm("eieio");
+    if(G_verbosity_level > 1)
+        printf("val=%08x\n", val);
+    return val;
+}
+
+void write2(unsigned long addr, unsigned short val) {
+    volatile unsigned short* p = (volatile unsigned short*)addr;
+
+    if(G_verbosity_level > 1)
+        printf("write2: addr=%08x val=%04x -> *p=%04x\n", (unsigned int)addr, val,
+                ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
+
+    *p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
+    asm("eieio");
+}
+
+unsigned short read2(unsigned long addr) {
+    unsigned short val;
+    volatile unsigned short* p = (volatile unsigned short*)addr;
+
+    if(G_verbosity_level > 1)
+        printf("read2: addr=%08x ", (unsigned int)addr);
+    val = *p;
+    val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
+    asm("eieio");
+    if(G_verbosity_level > 1)
+        printf("*p=%04x -> val=%04x\n",
+            ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8), val);
+    return val;
+}
+
+void write4(unsigned long addr, unsigned long val) {
+    volatile unsigned long* p = (volatile unsigned long*)addr;
+
+    if(G_verbosity_level > 1)
+        printf("write4: addr=%08x val=%08x -> *p=%08x\n", (unsigned int)addr, (unsigned int)val,
+            (unsigned int)(((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
+            ((val & 0x00FF0000) >> 8)  | ((val & 0x0000FF00) << 8)));
+
+    *p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
+         ((val & 0x00FF0000) >> 8)  | ((val & 0x0000FF00) << 8);
+    asm("eieio");
+}
+
+unsigned long read4(unsigned long addr) {
+    unsigned long val;
+    volatile unsigned long* p = (volatile unsigned long*)addr;
+
+    if(G_verbosity_level > 1)
+        printf("read4: addr=%08x", (unsigned int)addr);
+
+    val = *p;
+    val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
+          ((val & 0x00FF0000) >> 8)  | ((val & 0x0000FF00) << 8);
+    asm("eieio");
+
+    if(G_verbosity_level > 1)
+        printf("*p=%04x -> val=%04x\n",
+            (unsigned int)(((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
+            ((val & 0x00FF0000) >> 8)  | ((val & 0x0000FF00) << 8)), (unsigned int)val);
+    return val;
+}
+
+void write4be(unsigned long addr, unsigned long val) {
+    volatile unsigned long* p = (volatile unsigned long*)addr;
+
+    if(G_verbosity_level > 1)
+        printf("write4: addr=%08x val=%08x\n", (unsigned int)addr, (unsigned int)val);
+    *p = val;
+    asm("eieio");
+}
+
+/** One byte configuration write on PSII.
+ *  Currently fixes destination PCI bus to PCI2, onboard
+ *  pci.
+ *  @param    hose    PCI Host controller information. Ignored.
+ *  @param    dev        Encoded PCI device/Bus and Function value.
+ *  @param    reg        PCI Configuration register number.
+ *  @param    val        Address of location for received byte.
+ *  @return Always Zero.
+ */
+static int psII_read_config_byte(
+                    struct    pci_controller *hose,
+                    pci_dev_t                dev,
+                    int                      reg,
+                    u8                       *val)
+{
+    write4be(PSII_CONFIG_ADDR,
+            PSII_CONFIG_DEST_PCI2 |  /* Operate on PCI2 bus interface . */
+            (PCI_BUS(dev) << 16) |
+            (PCI_DEV(dev) << 11) |
+            (PCI_FUNC(dev) << 8) |
+            ((reg & 0xFF) & ~3));  /* Configuation cycle type 0 */
+
+    *val = read1(PSII_CONFIG_DATA+(reg&0x03));
+    return(0);
+}
+
+/** One byte configuration write on PSII.
+ *  Currently fixes destination bus to PCI2, onboard
+ *  pci.
+ *  @param    hose    PCI Host controller information. Ignored.
+ *  @param    dev        Encoded PCI device/Bus and Function value.
+ *  @param    reg        PCI Configuration register number.
+ *  @param    val        Output byte.
+ *  @return Always Zero.
+ */
+static int psII_write_config_byte(
+                  struct    pci_controller    *hose,
+                  pci_dev_t                    dev,
+                  int                        reg,
+                  u8                        val)
+{
+    write4be(PSII_CONFIG_ADDR,
+            PSII_CONFIG_DEST_PCI2 |  /* Operate on PCI2 bus interface . */
+            (PCI_BUS(dev) << 16) |
+            (PCI_DEV(dev) << 11) |
+            (PCI_FUNC(dev) << 8) |
+            ((reg & 0xFF) & ~3));  /* Configuation cycle type 0 */
+
+    write1(PSII_CONFIG_DATA+(reg&0x03),(unsigned char )val);
+
+    return(0);
+}
+
+/** One word (16 bit) configuration read on PSII.
+ *  Currently fixes destination PCI bus to PCI2, onboard
+ *  pci.
+ *  @param    hose    PCI Host controller information. Ignored.
+ *  @param    dev        Encoded PCI device/Bus and Function value.
+ *  @param    reg        PCI Configuration register number.
+ *  @param    val        Address of location for received word.
+ *  @return Always Zero.
+ */
+static int psII_read_config_word(
+                    struct    pci_controller    *hose,
+                    pci_dev_t                dev,
+                    int                        reg,
+                    u16                        *val)
+{
+    write4be(PSII_CONFIG_ADDR,
+            PSII_CONFIG_DEST_PCI2 |  /* Operate on PCI2 bus interface . */
+            (PCI_BUS(dev) << 16) |
+            (PCI_DEV(dev) << 11) |
+            (PCI_FUNC(dev) << 8) |
+            ((reg & 0xFF) & ~3));  /* Configuation cycle type 0 */
+
+    *val = read2(PSII_CONFIG_DATA+(reg&0x03));
+    return(0);
+}
+
+/** One word (16 bit) configuration write on PSII.
+ *  Currently fixes destination bus to PCI2, onboard
+ *  pci.
+ *  @param    hose    PCI Host controller information. Ignored.
+ *  @param    dev        Encoded PCI device/Bus and Function value.
+ *  @param    reg        PCI Configuration register number.
+ *  @param    val        Output word.
+ *  @return Always Zero.
+ */
+static int psII_write_config_word(
+                  struct    pci_controller    *hose,
+                  pci_dev_t                    dev,
+                  int                        reg,
+                  u16                        val)
+{
+    write4be(PSII_CONFIG_ADDR,
+            PSII_CONFIG_DEST_PCI2 |  /* Operate on PCI2 bus interface . */
+            (PCI_BUS(dev) << 16) |
+            (PCI_DEV(dev) << 11) |
+            (PCI_FUNC(dev) << 8) |
+            ((reg & 0xFF) & ~3));  /* Configuation cycle type 0 */
+
+    write2(PSII_CONFIG_DATA+(reg&0x03),(unsigned short )val);
+
+    return(0);
+}
+
+/** One DWord (32 bit) configuration read on PSII.
+ *  Currently fixes destination PCI bus to PCI2, onboard
+ *  pci.
+ *  @param    hose    PCI Host controller information. Ignored.
+ *  @param    dev        Encoded PCI device/Bus and Function value.
+ *  @param    reg        PCI Configuration register number.
+ *  @param    val        Address of location for received byte.
+ *  @return Always Zero.
+ */
+static int psII_read_config_dword(
+                    struct    pci_controller    *hose,
+                    pci_dev_t                dev,
+                    int                        reg,
+                    u32                        *val)
+{
+    write4be(PSII_CONFIG_ADDR,
+            PSII_CONFIG_DEST_PCI2 |  /* Operate on PCI2 bus interface . */
+            (PCI_BUS(dev) << 16) |
+            (PCI_DEV(dev) << 11) |
+            (PCI_FUNC(dev) << 8) |
+            ((reg & 0xFF) & ~3));  /* Configuation cycle type 0 */
+
+    *val = read4(PSII_CONFIG_DATA);
+    return(0);
+}
+
+/** One DWord (32 bit) configuration write on PSII.
+ *  Currently fixes destination bus to PCI2, onboard
+ *  pci.
+ *  @param    hose    PCI Host controller information. Ignored.
+ *  @param    dev        Encoded PCI device/Bus and Function value.
+ *  @param    reg        PCI Configuration register number.
+ *  @param    val        Output Dword.
+ *  @return Always Zero.
+ */
+static int psII_write_config_dword(
+                  struct    pci_controller    *hose,
+                  pci_dev_t                    dev,
+                  int                        reg,
+                  u32                        val)
+{
+    write4be(PSII_CONFIG_ADDR,
+            PSII_CONFIG_DEST_PCI2 |  /* Operate on PCI2 bus interface . */
+            (PCI_BUS(dev) << 16) |
+            (PCI_DEV(dev) << 11) |
+            (PCI_FUNC(dev) << 8) |
+            ((reg & 0xFF) & ~3));  /* Configuation cycle type 0 */
+
+    write4(PSII_CONFIG_DATA,(unsigned long)val);
+
+    return(0);
+}
+
+
+
+static struct pci_config_table    ap1000_config_table[] = {
+#ifdef CONFIG_AP1000
+    {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+    PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
+    pci_cfgfunc_config_device, 
+    {CFG_ETH_IOBASE, CFG_ETH_MEMBASE, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }},
+#endif
+    { }
+};
+
+
+static struct pci_controller psII_hose = {
+    config_table: ap1000_config_table,
+};
+
+void pci_init_board(void)
+{
+  struct pci_controller *hose = &psII_hose;
+
+  /*
+   * Register the hose
+   */
+  hose->first_busno = 0;
+  hose->last_busno = 0xff;
+
+
+  /* System memory space */
+  pci_set_region(hose->regions + 0,
+         AP1000_SYS_MEM_START, AP1000_SYS_MEM_START, AP1000_SYS_MEM_SIZE,
+         PCI_REGION_MEM | PCI_REGION_MEMORY);
+
+  /* PCI Memory space */
+  pci_set_region(hose->regions + 1,
+         PSII_PCI_MEM_BASE, PSII_PCI_MEM_BASE, PSII_PCI_MEM_SIZE,
+         PCI_REGION_MEM);
+
+  /* No IO Memory space  - for now */
+
+  pci_set_ops(hose,
+          psII_read_config_byte,
+          psII_read_config_word,
+          psII_read_config_dword,
+          psII_write_config_byte,
+          psII_write_config_word,
+          psII_write_config_dword);
+
+  hose->region_count = 2;
+
+  pci_register_hose(hose);
+
+  hose->last_busno = pci_hose_scan(hose);
+}
diff --git a/board/amirix/ap1000/powerspan.c b/board/amirix/ap1000/powerspan.c
new file mode 100644
index 0000000..fe395cc
--- /dev/null
+++ b/board/amirix/ap1000/powerspan.c
@@ -0,0 +1,712 @@
+/**
+ * @file powerspan.c Source file for PowerSpan II code.
+ */
+
+/*
+ * (C) Copyright 2005
+ * AMIRIX Systems Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/processor.h>
+#include "powerspan.h"
+#define tolower(x) x
+#include "ap1000.h"
+
+#ifdef INCLUDE_PCI
+
+/** Write one byte with byte swapping.
+  * @param  addr [IN] the address to write to
+  * @param  val  [IN] the value to write
+  */
+void write1(unsigned long addr, unsigned char val) {
+    volatile unsigned char* p = (volatile unsigned char*)addr;
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("write1: addr=%08x val=%02x\n", addr, val);
+    }
+#endif
+    *p = val;
+    PSII_SYNC();
+}
+
+/** Read one byte with byte swapping.
+  * @param  addr  [IN] the address to read from
+  * @return the value at addr
+  */
+unsigned char read1(unsigned long addr) {
+    unsigned char val;
+    volatile unsigned char* p = (volatile unsigned char*)addr;
+
+    val = *p;
+    PSII_SYNC();
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("read1: addr=%08x val=%02x\n", addr, val);
+    }
+#endif
+    return val;
+}
+
+/** Write one 2-byte word with byte swapping.
+  * @param  addr  [IN] the address to write to
+  * @param  val   [IN] the value to write
+  */
+void write2(unsigned long addr, unsigned short val) {
+    volatile unsigned short* p = (volatile unsigned short*)addr;
+
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("write2: addr=%08x val=%04x -> *p=%04x\n", addr, val,
+                ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
+        }
+#endif
+    *p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
+    PSII_SYNC();
+}
+
+/** Read one 2-byte word with byte swapping.
+  * @param  addr  [IN] the address to read from
+  * @return the value at addr
+  */
+unsigned short read2(unsigned long addr) {
+    unsigned short val;
+    volatile unsigned short* p = (volatile unsigned short*)addr;
+
+    val = *p;
+    val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
+    PSII_SYNC();
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("read2: addr=%08x *p=%04x -> val=%04x\n", addr, *p, val);
+    }
+#endif
+    return val;
+}
+
+/** Write one 4-byte word with byte swapping.
+  * @param  addr  [IN] the address to write to
+  * @param  val   [IN] the value to write
+  */
+void write4(unsigned long addr, unsigned long val) {
+    volatile unsigned long* p = (volatile unsigned long*)addr;
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("write4: addr=%08x val=%08x -> *p=%08x\n", addr, val,
+            ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
+            ((val & 0x00FF0000) >> 8)  | ((val & 0x0000FF00) << 8));
+        }
+#endif
+    *p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
+         ((val & 0x00FF0000) >> 8)  | ((val & 0x0000FF00) << 8);
+    PSII_SYNC();
+}
+
+/** Read one 4-byte word with byte swapping.
+  * @param  addr  [IN] the address to read from
+  * @return the value at addr
+  */
+unsigned long read4(unsigned long addr) {
+    unsigned long val;
+    volatile unsigned long* p = (volatile unsigned long*)addr;
+
+    val = *p;
+    val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
+          ((val & 0x00FF0000) >> 8)  | ((val & 0x0000FF00) << 8);
+    PSII_SYNC();
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("read4: addr=%08x *p=%08x -> val=%08x\n", addr, *p, val);
+    }
+#endif
+    return val;
+}
+
+int PCIReadConfig(int bus, int dev, int fn, int reg, int width, unsigned long* val){
+    unsigned int conAdrVal;
+    unsigned int conDataReg = REG_CONFIG_DATA;
+    unsigned int status;
+    int ret_val = 0;
+
+
+    /* DEST bit hardcoded to 1: local pci is PCI-2 */
+    /* TYPE bit is hardcoded to 1: all config cycles are local */
+    conAdrVal = (1 << 24)
+              | ((bus & 0xFF) << 16)
+              | ((dev & 0xFF) << 11)
+              | ((fn & 0x07)  <<  8)
+              | (reg & 0xFC);
+
+    /* clear any pending master aborts */
+    write4(REG_P1_CSR, CLEAR_MASTER_ABORT);
+
+    /* Load the conAdrVal value first, then read from pb_conf_data */
+    write4(REG_CONFIG_ADDRESS, conAdrVal);
+    PSII_SYNC();
+
+
+    /* Note: documentation does not match the pspan library code */
+    /* Note: *pData comes back as -1 if device is not present */
+    switch (width){
+        case 4:{
+          *(unsigned int*)val = read4(conDataReg);
+          break;
+        }
+        case 2:{
+          *(unsigned short*)val = read2(conDataReg);
+          break;
+        }
+        case 1:{
+          *(unsigned char*)val = read1(conDataReg);
+          break;
+        }
+        default:{
+          ret_val = ILLEGAL_REG_OFFSET;
+          break;
+        }
+    }
+    PSII_SYNC();
+
+    /* clear any pending master aborts */
+    status = read4(REG_P1_CSR);
+    if(status & CLEAR_MASTER_ABORT){
+        ret_val = NO_DEVICE_FOUND;
+        write4(REG_P1_CSR, CLEAR_MASTER_ABORT);
+    }
+
+    return ret_val;
+}
+
+
+int PCIWriteConfig(int bus, int dev, int fn, int reg, int width, unsigned long val){
+    unsigned int conAdrVal;
+    unsigned int conDataReg = REG_CONFIG_DATA;
+    unsigned int status;
+    int ret_val = 0;
+
+
+    /* DEST bit hardcoded to 1: local pci is PCI-2 */
+    /* TYPE bit is hardcoded to 1: all config cycles are local */
+    conAdrVal = (1 << 24)
+              | ((bus & 0xFF) << 16)
+              | ((dev & 0xFF) << 11)
+              | ((fn & 0x07)  <<  8)
+              | (reg & 0xFC);
+
+    /* clear any pending master aborts */
+    write4(REG_P1_CSR, CLEAR_MASTER_ABORT);
+
+    /* Load the conAdrVal value first, then read from pb_conf_data */
+    write4(REG_CONFIG_ADDRESS, conAdrVal);
+    PSII_SYNC();
+
+
+    /* Note: documentation does not match the pspan library code */
+    /* Note: *pData comes back as -1 if device is not present */
+    switch (width){
+        case 4:{
+          write4(conDataReg, val);
+          break;
+        }
+        case 2:{
+          write2(conDataReg, val);
+          break;
+        }
+        case 1:{
+          write1(conDataReg, val);
+          break;
+        }
+        default:{
+          ret_val = ILLEGAL_REG_OFFSET;
+          break;
+        }
+    }
+    PSII_SYNC();
+
+    /* clear any pending master aborts */
+    status = read4(REG_P1_CSR);
+    if(status & CLEAR_MASTER_ABORT){
+        ret_val = NO_DEVICE_FOUND;
+        write4(REG_P1_CSR, CLEAR_MASTER_ABORT);
+    }
+
+    return ret_val;
+}
+
+
+int pci_read_config_byte(int bus, int dev, int fn, int reg, unsigned char* val){
+    unsigned long read_val;
+    int ret_val;
+
+    ret_val = PCIReadConfig(bus, dev, fn, reg, 1, &read_val);
+    *val = read_val & 0xFF;
+
+    return ret_val;
+}
+
+int pci_write_config_byte(int bus, int dev, int fn, int reg, unsigned char val){
+    return PCIWriteConfig(bus, dev, fn, reg, 1, val);
+}
+
+int pci_read_config_word(int bus, int dev, int fn, int reg, unsigned short* val){
+    unsigned long read_val;
+    int ret_val;
+
+    ret_val = PCIReadConfig(bus, dev, fn, reg, 2, &read_val);
+    *val = read_val & 0xFFFF;
+
+    return ret_val;
+}
+
+int pci_write_config_word(int bus, int dev, int fn, int reg, unsigned short val){
+    return PCIWriteConfig(bus, dev, fn, reg, 2, val);
+}
+
+int pci_read_config_dword(int bus, int dev, int fn, int reg, unsigned long* val){
+    return PCIReadConfig(bus, dev, fn, reg, 4, val);
+}
+
+int pci_write_config_dword(int bus, int dev, int fn, int reg, unsigned long val){
+    return PCIWriteConfig(bus, dev, fn, reg, 4, val);
+}
+
+#endif /* INCLUDE_PCI */
+
+int I2CAccess(unsigned char theI2CAddress, unsigned char theDevCode, unsigned char theChipSel, unsigned char* theValue, int RWFlag){
+    int ret_val = 0;
+    unsigned int reg_value;
+
+    reg_value = PowerSpanRead(REG_I2C_CSR);
+
+    if(reg_value & I2C_CSR_ACT){
+        printf("Error: I2C busy\n");
+        ret_val = I2C_BUSY;
+    }
+    else{
+        reg_value = ((theI2CAddress & 0xFF) << 24)
+                  | ((theDevCode & 0x0F) << 12)
+                  | ((theChipSel & 0x07) << 9)
+                  | I2C_CSR_ERR;
+        if(RWFlag == I2C_WRITE){
+            reg_value |= I2C_CSR_RW | ((*theValue & 0xFF) << 16);
+        }
+
+        PowerSpanWrite(REG_I2C_CSR, reg_value);
+        udelay(1);
+
+        do{
+            reg_value = PowerSpanRead(REG_I2C_CSR);
+
+            if((reg_value & I2C_CSR_ACT) == 0){
+                if(reg_value & I2C_CSR_ERR){
+                    ret_val = I2C_ERR;
+                }
+                else{
+                    *theValue = (reg_value & I2C_CSR_DATA) >> 16;
+                }
+            }
+        } while(reg_value & I2C_CSR_ACT);
+    }
+
+    return ret_val;
+}
+
+int EEPROMRead(unsigned char theI2CAddress, unsigned char* theValue){
+    return I2CAccess(theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL, theValue, I2C_READ);
+}
+
+int EEPROMWrite(unsigned char theI2CAddress, unsigned char theValue){
+    return I2CAccess(theI2CAddress, I2C_EEPROM_DEV, I2C_EEPROM_CHIP_SEL, &theValue, I2C_WRITE);
+}
+
+int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+    char cmd;
+    int ret_val = 0;
+    unsigned int address = 0;
+    unsigned char value = 1;
+    unsigned char read_value;
+    int ii;
+    int error = 0;
+    unsigned char* mem_ptr;
+    unsigned char default_eeprom[] = EEPROM_DEFAULT;
+
+    if(argc < 2){
+        goto usage;
+    }
+
+    cmd = argv[1][0];
+    if(argc > 2){
+        address = simple_strtoul(argv[2], NULL, 16);
+        if(argc > 3){
+            value = simple_strtoul(argv[3], NULL, 16) & 0xFF;
+        }
+    }
+
+    switch (cmd){
+        case 'r':{
+            if(address > 256){
+                printf("Illegal Address\n");
+                goto usage;
+            }
+            printf("@0x%x: ", address);
+            for(ii = 0;ii < value;ii++){
+                if(EEPROMRead(address + ii, &read_value) != 0){
+                    printf("Read Error\n");
+                }
+                else{
+                    printf("0x%02x ", read_value);
+                }
+
+                if(((ii + 1) % 16) == 0){
+                    printf("\n");
+                }
+            }
+            printf("\n");
+            break;
+        }
+        case 'w':{
+            if(address > 256){
+                printf("Illegal Address\n");
+                goto usage;
+            }
+            if(argc < 4){
+                goto usage;
+            }
+            if(EEPROMWrite(address, value) != 0){
+                printf("Write Error\n");
+            }
+            break;
+        }
+        case 'g':{
+            if(argc != 3){
+                goto usage;
+            }
+            mem_ptr = (unsigned char*)address;
+            for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){
+                if(EEPROMRead(ii, &read_value) != 0){
+                    printf("Read Error\n");
+                    error = 1;
+                }
+                else{
+                    *mem_ptr = read_value;
+                    mem_ptr++;
+                }
+            }
+            break;
+        }
+        case 'p':{
+            if(argc != 3){
+                goto usage;
+            }
+            mem_ptr = (unsigned char*)address;
+            for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){
+                if(EEPROMWrite(ii, *mem_ptr) != 0){
+                    printf("Write Error\n");
+                    error = 1;
+                }
+
+                mem_ptr++;
+            }
+            break;
+        }
+        case 'd':{
+            if(argc != 2){
+                goto usage;
+            }
+            for(ii = 0;((ii < EEPROM_LENGTH) && (error == 0));ii++){
+                if(EEPROMWrite(ii, default_eeprom[ii]) != 0){
+                    printf("Write Error\n");
+                    error = 1;
+                }
+            }
+            break;
+        }
+        default:{
+            goto usage;
+        }
+    }
+
+    goto done;
+ usage:
+    printf ("Usage:\n%s\n", cmdtp->help);
+
+ done:
+     return ret_val;
+
+}
+
+U_BOOT_CMD(
+    eeprom,    4,    0,    do_eeprom,
+    "eeprom  - read/write/copy to/from the PowerSpan II eeprom\n",
+    "eeprom r OFF [NUM]\n"
+    "    - read NUM words starting at OFF\n"
+    "eeprom w OFF VAL\n"
+    "    - write word VAL at offset OFF\n"
+    "eeprom g ADD\n"
+    "    - store contents of eeprom at address ADD\n"
+    "eeprom p ADD\n"
+    "    - put data stored at address ADD into the eeprom\n"
+    "eeprom d\n"
+    "    - return eeprom to default contents\n"
+);
+
+unsigned int PowerSpanRead(unsigned int theOffset){
+    volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset);
+    unsigned int ret_val;
+
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("PowerSpanRead: offset=%08x ", theOffset);
+    }
+#endif
+    ret_val = *ptr;
+    PSII_SYNC();
+
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("value=%08x\n", ret_val);
+    }
+#endif
+
+    return ret_val;
+}
+
+void PowerSpanWrite(unsigned int theOffset, unsigned int theValue){
+    volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset);
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("PowerSpanWrite: offset=%08x val=%02x\n", theOffset, theValue);
+    }
+#endif
+    *ptr = theValue;
+    PSII_SYNC();
+}
+
+/**
+ * Sets the indicated bits in the indicated register.
+ * @param theOffset [IN] the register to access.
+ * @param theMask   [IN] bits set in theMask will be set in the register.
+ */
+void PowerSpanSetBits(unsigned int theOffset, unsigned int theMask){
+    volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset);
+    unsigned int register_value;
+
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("PowerSpanSetBits: offset=%08x mask=%02x\n", theOffset, theMask);
+    }
+#endif
+    register_value = *ptr;
+    PSII_SYNC();
+
+    register_value |= theMask;
+    *ptr = register_value;
+    PSII_SYNC();
+}
+
+/**
+ * Clears the indicated bits in the indicated register.
+ * @param theOffset [IN] the register to access.
+ * @param theMask   [IN] bits set in theMask will be cleared in the register.
+ */
+void PowerSpanClearBits(unsigned int theOffset, unsigned int theMask){
+    volatile unsigned int* ptr = (volatile unsigned int*)(PSPAN_BASEADDR + theOffset);
+    unsigned int register_value;
+
+#ifdef VERBOSITY
+    if(gVerbosityLevel > 1){
+        printf("PowerSpanClearBits: offset=%08x mask=%02x\n", theOffset, theMask);
+    }
+#endif
+    register_value = *ptr;
+    PSII_SYNC();
+
+    register_value &= ~theMask;
+    *ptr = register_value;
+    PSII_SYNC();
+}
+
+/**
+ * Configures a slave image on the local bus, based on the parameters and some hardcoded system values.
+ * Slave Images are images that cause the PowerSpan II to be a master on the PCI bus.  Thus, they
+ *  are outgoing from the standpoint of the local bus.
+ * @param theImageIndex    [IN] the PowerSpan II image to set (assumed to be 0-7).
+ * @param theBlockSize     [IN] the block size of the image (as used by PowerSpan II: PB_SIx_CTL[BS]).
+ * @param theMemIOFlag     [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
+ * @param theEndianness    [IN] the endian bits for the image (already shifted, use defines).
+ * @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
+ * @param thePCIBaseAddr   [IN] the PCI address for the image (assumed to be valid with provided block size).
+ */
+int SetSlaveImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr){
+    unsigned int reg_offset = theImageIndex * PB_SLAVE_IMAGE_OFF;
+    unsigned int reg_value = 0;
+
+    /* Make sure that the Slave Image is disabled */
+    PowerSpanClearBits((REGS_PB_SLAVE_CSR + reg_offset), PB_SLAVE_CSR_IMG_EN);
+
+    /* Setup the mask required for requested PB Slave Image configuration */
+    reg_value = PB_SLAVE_CSR_TA_EN | theEndianness | (theBlockSize << 24);
+    if(theMemIOFlag == PB_SLAVE_USE_MEM_IO){
+        reg_value |= PB_SLAVE_CSR_MEM_IO;
+    }
+
+    /* hardcoding the following:
+        TA_EN = 1
+        MD_EN = 0
+        MODE  = 0
+        PRKEEP = 0
+        RD_AMT = 0
+    */
+    PowerSpanWrite((REGS_PB_SLAVE_CSR + reg_offset), reg_value);
+
+    /* these values are not checked by software */
+    PowerSpanWrite((REGS_PB_SLAVE_BADDR + reg_offset), theLocalBaseAddr);
+    PowerSpanWrite((REGS_PB_SLAVE_TADDR + reg_offset), thePCIBaseAddr);
+
+    /* Enable the Slave Image */
+    PowerSpanSetBits((REGS_PB_SLAVE_CSR + reg_offset), PB_SLAVE_CSR_IMG_EN);
+
+    return 0;
+}
+
+/**
+ * Configures a target image on the local bus, based on the parameters and some hardcoded system values.
+ * Target Images are used when the PowerSpan II is acting as a target for an access.  Thus, they
+ *  are incoming from the standpoint of the local bus.
+ * In order to behave better on the host PCI bus, if thePCIBaseAddr is NULL (0x00000000), then the PCI
+ *  base address will not be updated; makes sense given that the hosts own memory should be mapped to
+ *  PCI address 0x00000000.
+ * @param theImageIndex    [IN] the PowerSpan II image to set.
+ * @param theBlockSize     [IN] the block size of the image (as used by PowerSpan II: Px_TIx_CTL[BS]).
+ * @param theMemIOFlag     [IN] if PX_TGT_USE_MEM_IO, this image will have the MEM_IO bit set.
+ * @param theEndianness    [IN] the endian bits for the image (already shifted, use defines).
+ * @param theLocalBaseAddr [IN] the Local address for the image (assumed to be valid with provided block size).
+ * @param thePCIBaseAddr   [IN] the PCI address for the image (assumed to be valid with provided block size).
+ */
+int SetTargetImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr){
+    unsigned int csr_reg_offset = theImageIndex * P1_TGT_IMAGE_OFF;
+    unsigned int pci_reg_offset = theImageIndex * P1_BST_OFF;
+    unsigned int reg_value = 0;
+
+    /* Make sure that the Slave Image is disabled */
+    PowerSpanClearBits((REGS_P1_TGT_CSR + csr_reg_offset), PB_SLAVE_CSR_IMG_EN);
+
+    /* Setup the mask required for requested PB Slave Image configuration */
+    reg_value = PX_TGT_CSR_TA_EN | PX_TGT_CSR_BAR_EN | (theBlockSize << 24) | PX_TGT_CSR_RTT_READ | PX_TGT_CSR_WTT_WFLUSH | theEndianness;
+    if(theMemIOFlag == PX_TGT_USE_MEM_IO){
+        reg_value |= PX_TGT_MEM_IO;
+    }
+
+    /* hardcoding the following:
+        TA_EN = 1
+        BAR_EN = 1
+        MD_EN = 0
+        MODE  = 0
+        DEST  = 0
+        RTT = 01010
+        GBL = 0
+        CI = 0
+        WTT = 00010
+        PRKEEP = 0
+        MRA = 0
+        RD_AMT = 0
+    */
+    PowerSpanWrite((REGS_P1_TGT_CSR + csr_reg_offset), reg_value);
+
+    PowerSpanWrite((REGS_P1_TGT_TADDR + csr_reg_offset), theLocalBaseAddr);
+
+    if(thePCIBaseAddr != (unsigned int)NULL){
+        PowerSpanWrite((REGS_P1_BST + pci_reg_offset), thePCIBaseAddr);
+    }
+
+    /* Enable the Slave Image */
+    PowerSpanSetBits((REGS_P1_TGT_CSR + csr_reg_offset), PB_SLAVE_CSR_IMG_EN);
+
+    return 0;
+}
+
+int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
+    char cmd;
+    int ret_val = 1;
+    unsigned int image_index;
+    unsigned int block_size;
+    unsigned int mem_io;
+    unsigned int local_addr;
+    unsigned int pci_addr;
+    int endianness;
+
+    if(argc != 8){
+        goto usage;
+    }
+
+    cmd = argv[1][0];
+    image_index = simple_strtoul(argv[2], NULL, 16);
+    block_size  = simple_strtoul(argv[3], NULL, 16);
+    mem_io      = simple_strtoul(argv[4], NULL, 16);
+    endianness  = argv[5][0];
+    local_addr  = simple_strtoul(argv[6], NULL, 16);
+    pci_addr    = simple_strtoul(argv[7], NULL, 16);
+
+
+    switch (cmd){
+        case 'i':{
+            if(tolower(endianness) == 'b'){
+                endianness = PX_TGT_CSR_BIG_END;
+            }
+            else if(tolower(endianness) == 'l'){
+                endianness = PX_TGT_CSR_TRUE_LEND;
+            }
+            else{
+                goto usage;
+            }
+            SetTargetImage(image_index, block_size, mem_io, endianness, local_addr, pci_addr);
+            break;
+        }
+        case 'o':{
+            if(tolower(endianness) == 'b'){
+                endianness = PB_SLAVE_CSR_BIG_END;
+            }
+            else if(tolower(endianness) == 'l'){
+                endianness = PB_SLAVE_CSR_TRUE_LEND;
+            }
+            else{
+                goto usage;
+            }
+            SetSlaveImage(image_index, block_size, mem_io, endianness, local_addr, pci_addr);
+            break;
+        }
+        default:{
+            goto usage;
+        }
+    }
+
+    goto done;
+ usage:
+    printf ("Usage:\n%s\n", cmdtp->help);
+
+ done:
+     return ret_val;
+
+}
+
+
+
diff --git a/board/amirix/ap1000/powerspan.h b/board/amirix/ap1000/powerspan.h
new file mode 100644
index 0000000..4e9a8c1
--- /dev/null
+++ b/board/amirix/ap1000/powerspan.h
@@ -0,0 +1,170 @@
+/**
+ * @file powerspan.h Header file for PowerSpan II code.
+ */
+
+/*
+ * (C) Copyright 2005
+ * AMIRIX Systems Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef POWERSPAN_H
+#define POWERSPAN_H
+
+#define CLEAR_MASTER_ABORT 0xdeadbeef
+#define NO_DEVICE_FOUND     -1
+#define ILLEGAL_REG_OFFSET  -2
+#define I2C_BUSY            -3
+#define I2C_ERR             -4
+
+#define REG_P1_CSR          0x004
+#define REGS_P1_BST         0x018
+#define REG_P1_ERR_CSR      0x150
+#define REG_P1_MISC_CSR     0x160
+#define REGS_P1_TGT_CSR     0x100
+#define REGS_P1_TGT_TADDR   0x104
+#define REGS_PB_SLAVE_CSR   0x200
+#define REGS_PB_SLAVE_TADDR 0x204
+#define REGS_PB_SLAVE_BADDR 0x208
+#define REG_CONFIG_ADDRESS  0x290
+#define REG_CONFIG_DATA     0x294
+#define REG_PB_ERR_CSR      0x2B0
+#define REG_PB_MISC_CSR     0x2C0
+#define REG_MISC_CSR        0x400
+#define REG_I2C_CSR         0x408
+#define REG_RESET_CSR       0x40C
+#define REG_ISR0            0x410
+#define REG_ISR1            0x414
+#define REG_IER0            0x418
+#define REG_MBOX_MAP        0x420
+#define REG_HW_MAP          0x42C
+#define REG_IDR             0x444
+
+#define CSR_MEMORY_SPACE_ENABLE 0x00000002
+#define CSR_PCI_MASTER_ENABLE   0x00000004
+
+#define P1_BST_OFF  0x04
+
+#define PX_ERR_ERR_STATUS   0x01000000
+
+#define PX_MISC_CSR_MAX_RETRY_MASK  0x00000F00
+#define PX_MISC_CSR_MAX_RETRY       0x00000F00
+#define PX_MISC_REG_BAR_ENABLE      0x00008000
+#define PB_MISC_TEA_ENABLE          0x00000010
+#define PB_MISC_MAC_TEA             0x00000040
+
+#define P1_TGT_IMAGE_OFF    0x010
+#define PX_TGT_CSR_IMG_EN   0x80000000
+#define PX_TGT_CSR_TA_EN    0x40000000
+#define PX_TGT_CSR_BAR_EN   0x20000000
+#define PX_TGT_CSR_MD_EN    0x10000000
+#define PX_TGT_CSR_MODE     0x00800000
+#define PX_TGT_CSR_DEST     0x00400000
+#define PX_TGT_CSR_MEM_IO   0x00200000
+#define PX_TGT_CSR_GBL      0x00080000
+#define PX_TGT_CSR_CL       0x00040000
+#define PX_TGT_CSR_PRKEEP   0x00000080
+
+#define PX_TGT_CSR_BS_MASK      0x0F000000
+#define PX_TGT_MEM_IO           0x00200000
+#define PX_TGT_CSR_RTT_MASK     0x001F0000
+#define PX_TGT_CSR_RTT_READ     0x000A0000
+#define PX_TGT_CSR_WTT_MASK     0x00001F00
+#define PX_TGT_CSR_WTT_WFLUSH   0x00000200
+#define PX_TGT_CSR_END_MASK     0x00000060
+#define PX_TGT_CSR_BIG_END      0x00000040
+#define PX_TGT_CSR_TRUE_LEND    0x00000060
+#define PX_TGT_CSR_RDAMT_MASK   0x00000007
+
+#define PX_TGT_CSR_BS_64MB  0xa
+#define PX_TGT_CSR_BS_16MB  0x8
+
+#define PX_TGT_USE_MEM_IO   1
+#define PX_TGT_NOT_MEM_IO   0
+
+#define PB_SLAVE_IMAGE_OFF  0x010
+#define PB_SLAVE_CSR_IMG_EN 0x80000000
+#define PB_SLAVE_CSR_TA_EN  0x40000000
+#define PB_SLAVE_CSR_MD_EN  0x20000000
+#define PB_SLAVE_CSR_MODE   0x00800000
+#define PB_SLAVE_CSR_DEST   0x00400000
+#define PB_SLAVE_CSR_MEM_IO 0x00200000
+#define PB_SLAVE_CSR_PRKEEP 0x00000080
+
+#define PB_SLAVE_CSR_BS_MASK    0x1F000000
+#define PB_SLAVE_CSR_END_MASK   0x00000060
+#define PB_SLAVE_CSR_BIG_END    0x00000040
+#define PB_SLAVE_CSR_TRUE_LEND  0x00000060
+#define PB_SLAVE_CSR_RDAMT_MASK 0x00000007
+
+#define PB_SLAVE_USE_MEM_IO 1
+#define PB_SLAVE_NOT_MEM_IO 0
+
+
+#define MISC_CSR_PCI1_LOCK  0x00000080
+
+#define I2C_CSR_ADDR      0xFF000000  /* Specifies I2C Device Address to be Accessed */
+#define I2C_CSR_DATA      0x00FF0000  /* Specifies the Required Data for a Write */
+#define I2C_CSR_DEV_CODE  0x0000F000  /* Device Select. I2C 4-bit Device Code */
+#define I2C_CSR_CS        0x00000E00  /* Chip Select */
+#define I2C_CSR_RW        0x00000100  /* Read/Write */
+#define I2C_CSR_ACT       0x00000080  /* I2C Interface Active */
+#define I2C_CSR_ERR       0x00000040  /* Error */
+
+#define I2C_EEPROM_DEV      0xa
+#define I2C_EEPROM_CHIP_SEL 0
+
+#define I2C_READ    0
+#define I2C_WRITE   1
+
+#define RESET_CSR_EEPROM_LOAD 0x00000010
+
+#define ISR_CLEAR_ALL   0xFFFFFFFF
+
+#define IER0_DMA_INTS_EN    0x0F000000
+#define IER0_PCI_1_EN       0x00400000
+#define IER0_HW_INTS_EN     0x003F0000
+#define IER0_MB_INTS_EN     0x000000FF
+#define IER0_DEFAULT        (IER0_DMA_INTS_EN | IER0_PCI_1_EN | IER0_HW_INTS_EN | IER0_MB_INTS_EN)
+
+#define MBOX_MAP_TO_INT4    0xCCCCCCCC
+
+#define HW_MAP_HW4_TO_INT4  0x000C0000
+
+#define IDR_PCI_A_OUT   0x40000000
+#define IDR_MBOX_OUT    0x10000000
+
+
+int pci_read_config_byte(int bus, int dev, int fn, int reg, unsigned char* val);
+int pci_write_config_byte(int bus, int dev, int fn, int reg, unsigned char val);
+int pci_read_config_word(int bus, int dev, int fn, int reg, unsigned short* val);
+int pci_write_config_word(int bus, int dev, int fn, int reg, unsigned short val);
+int pci_read_config_dword(int bus, int dev, int fn, int reg, unsigned long* val);
+int pci_write_config_dword(int bus, int dev, int fn, int reg, unsigned long val);
+
+unsigned int PowerSpanRead(unsigned int theOffset);
+void PowerSpanWrite(unsigned int theOffset, unsigned int theValue);
+
+int I2CAccess(unsigned char theI2CAddress, unsigned char theDevCode, unsigned char theChipSel, unsigned char* theValue, int RWFlag);
+
+int PCIWriteConfig(int bus, int dev, int fn, int reg, int width, unsigned long val);
+int PCIReadConfig(int bus, int dev, int fn, int reg, int width, unsigned long* val);
+
+int SetSlaveImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr);
+int SetTargetImage(int theImageIndex, unsigned int theBlockSize, int theMemIOFlag, int theEndianness, unsigned int theLocalBaseAddr, unsigned int thePCIBaseAddr);
+
+#endif
diff --git a/board/amirix/ap1000/serial.c b/board/amirix/ap1000/serial.c
new file mode 100644
index 0000000..431e469
--- /dev/null
+++ b/board/amirix/ap1000/serial.c
@@ -0,0 +1,128 @@
+/*
+ * (C) Copyright 2002
+ * Peter De Schrijver (p2@mind.be), Mind Linux Solutions, NV.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <asm/u-boot.h>
+#include <asm/processor.h>
+#include <common.h>
+#include <command.h>
+#include <config.h>
+
+#include <ns16550.h>
+
+#if 0
+#include "serial.h"
+#endif
+
+const NS16550_t COM_PORTS[] = { (NS16550_t) CFG_NS16550_COM1, (NS16550_t) CFG_NS16550_COM2 };
+
+#undef CFG_DUART_CHAN
+#define CFG_DUART_CHAN gComPort
+static int gComPort = 0;
+
+int
+serial_init (void)
+{
+    DECLARE_GLOBAL_DATA_PTR;
+
+    int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+    (void)NS16550_init(COM_PORTS[0], clock_divisor);
+    gComPort = 0;
+
+    return 0;
+
+}
+
+void
+serial_putc(const char c)
+{
+    if (c == '\n'){
+        NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
+    }
+
+    NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
+}
+
+int
+serial_getc(void)
+{
+    return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+int
+serial_tstc(void)
+{
+    return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+void
+serial_setbrg (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+    int clock_divisor = CFG_NS16550_CLK / 16 / gd->baudrate;
+
+#ifdef CFG_INIT_CHAN1
+    NS16550_reinit(COM_PORTS[0], clock_divisor);
+#endif
+#ifdef CFG_INIT_CHAN2
+    NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+}
+
+void
+serial_puts (const char *s)
+{
+	while (*s) {
+		serial_putc (*s++);
+	}
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void
+kgdb_serial_init(void)
+{
+}
+
+void
+putDebugChar (int c)
+{
+	serial_putc (c);
+}
+
+void
+putDebugStr (const char *str)
+{
+	serial_puts (str);
+}
+
+int
+getDebugChar (void)
+{
+	return serial_getc();
+}
+
+void
+kgdb_interruptible (int yes)
+{
+	return;
+}
+#endif	/* CFG_CMD_KGDB	*/
diff --git a/board/amirix/ap1000/u-boot.lds b/board/amirix/ap1000/u-boot.lds
new file mode 100644
index 0000000..97e8290
--- /dev/null
+++ b/board/amirix/ap1000/u-boot.lds
@@ -0,0 +1,144 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within	*/
+    /* the sector layout of our flash chips!	XXX FIXME XXX	*/
+
+    cpu/ppc4xx/start.o	(.text)
+    board/amirix/ap1000/init.o	(.text)
+    cpu/ppc4xx/kgdb.o	(.text)
+    cpu/ppc4xx/traps.o	(.text)
+    cpu/ppc4xx/interrupts.o	(.text)
+    cpu/ppc4xx/serial.o	(.text)
+    cpu/ppc4xx/cpu_init.o	(.text)
+    cpu/ppc4xx/speed.o	(.text)
+    common/dlmalloc.o	(.text)
+    lib_generic/crc32.o		(.text)
+    lib_ppc/extable.o	(.text)
+    lib_generic/zlib.o		(.text)
+
+/*    . = env_offset;*/
+/*    common/environment.o(.text)*/
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index 469f97d..cbd7b24 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -381,6 +381,13 @@
 extern void get_sys_info (sys_info_t * sysInfo);
 extern ulong get_PCI_freq (void);
 
+#elif defined(CONFIG_AP1000)
+void get_sys_info (sys_info_t * sysInfo) {
+	sysInfo->freqProcessor = 240 * 1000 * 1000;
+	sysInfo->freqPLB = 80 * 1000 * 1000;
+	sysInfo->freqPCI = 33 * 1000 * 1000;
+}
+
 #elif defined(CONFIG_405)
 
 void get_sys_info (sys_info_t * sysInfo) {
diff --git a/drivers/e1000.c b/drivers/e1000.c
index cc50c26..787134a 100644
--- a/drivers/e1000.c
+++ b/drivers/e1000.c
@@ -112,6 +112,7 @@
 	readl((a)->hw_addr + E1000_##reg + ((offset) << 2)))
 #define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}
 
+#ifndef CONFIG_AP1000 /* remove for warnings */
 /******************************************************************************
  * Raises the EEPROM's clock input.
  *
@@ -478,6 +479,7 @@
 		return -E1000_ERR_EEPROM;
 	}
 }
+#endif /* #ifndef CONFIG_AP1000 */
 
 /******************************************************************************
  * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
@@ -488,6 +490,7 @@
 static int
 e1000_read_mac_addr(struct eth_device *nic)
 {
+#ifndef CONFIG_AP1000
 	struct e1000_hw *hw = nic->priv;
 	uint16_t offset;
 	uint16_t eeprom_data;
@@ -509,6 +512,32 @@
 		/* Invert the last bit if this is the second device */
 		nic->enetaddr[5] += 1;
 	}
+#else
+	/*
+	 * The AP1000's e1000 has no eeprom; the MAC address is stored in the
+	 * environment variables.  Currently this does not support the addition
+	 * of a PMC e1000 card, which is certainly a possibility, so this should
+	 * be updated to properly use the env variable only for the onboard e1000
+	 */
+
+	int ii;
+	char *s, *e;
+
+	DEBUGFUNC();
+
+	s = getenv ("ethaddr");
+	if (s == NULL){
+		return -E1000_ERR_EEPROM;
+	}
+	else{
+		for(ii = 0; ii < 6; ii++) {
+			nic->enetaddr[ii] = s ? simple_strtoul (s, &e, 16) : 0;
+			if (s){
+				s = (*e) ? e + 1 : e;
+			}
+		}
+	}
+#endif
 	return 0;
 }
 
@@ -876,6 +905,7 @@
 
 	DEBUGFUNC();
 
+#ifndef CONFIG_AP1000
 	/* Read and store word 0x0F of the EEPROM. This word contains bits
 	 * that determine the hardware's default PAUSE (flow control) mode,
 	 * a bit that determines whether the HW defaults to enabling or
@@ -888,6 +918,11 @@
 		DEBUGOUT("EEPROM Read Error\n");
 		return -E1000_ERR_EEPROM;
 	}
+#else
+	/* we have to hardcode the proper value for our hardware. */
+	/* this value is for the 82540EM pci card used for prototyping, and it works. */
+	eeprom_data = 0xb220;
+#endif
 
 	if (hw->fc == e1000_fc_default) {
 		if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
@@ -2950,12 +2985,14 @@
 			free(nic);
 			return 0;
 		}
+#ifndef CONFIG_AP1000
 		if (e1000_validate_eeprom_checksum(nic) < 0) {
 			printf("The EEPROM Checksum Is Not Valid\n");
 			free(hw);
 			free(nic);
 			return 0;
 		}
+#endif
 		e1000_read_mac_addr(nic);
 
 		E1000_WRITE_REG(hw, PBA, E1000_DEFAULT_PBA);
diff --git a/include/configs/AP1000.h b/include/configs/AP1000.h
new file mode 100644
index 0000000..d9c4b5b
--- /dev/null
+++ b/include/configs/AP1000.h
@@ -0,0 +1,255 @@
+/*
+ * AMIRIX.h: AMIRIX specific config options
+ *
+ * Author : Frank Smith (smith at amirix dot com)
+ *
+ * Derived from : other configuration header files in this tree
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire
+ * program is licensed under the GPL.
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#undef DEBUG
+
+#define CONFIG_405  1      /* This is a PPC405 CPU     */
+#define CONFIG_4xx  1      /* ...member of PPC4xx family   */
+
+#define CONFIG_AP1000  1   /* ...on an AP1000 board    */
+
+#define CONFIG_PCI 1
+
+#define CFG_HUSH_PARSER		1	/* use "hush" command parser    */
+#define CFG_PROMPT			"0> "
+#define CFG_PROMPT_HUSH_PS2	"> "
+
+#define CONFIG_COMMAND_EDIT 1
+#define CONFIG_COMMAND_HISTORY 1
+#define CONFIG_COMPLETE_ADDRESSES 1
+
+#define CFG_ENV_IS_IN_FLASH     1
+#define CFG_FLASH_USE_BUFFER_WRITE
+
+#ifdef CFG_ENV_IS_IN_NVRAM
+#undef CFG_ENV_IS_IN_FLASH
+#else
+#ifdef CFG_ENV_IS_IN_FLASH
+#undef CFG_ENV_IS_IN_NVRAM
+#endif
+#endif
+
+#define CONFIG_BAUDRATE     57600
+#define CONFIG_BOOTDELAY    3  /* autoboot after 3 seconds */
+
+#define CONFIG_BOOTCOMMAND  ""      /* autoboot command */
+
+/* Size (bytes) of interrupt driven serial port buffer.
+ * Set to 0 to use polling instead of interrupts.
+ * Setting to 0 will also disable RTS/CTS handshaking.
+ */
+#undef  CONFIG_SERIAL_SOFTWARE_FIFO
+
+#define CONFIG_BOOTARGS     "console=ttyS0,57600"
+
+#define CONFIG_LOADS_ECHO   1   /* echo on for serial download  */
+#define CFG_LOADS_BAUD_CHANGE   1   /* allow baudrate change    */
+
+
+
+#define CONFIG_COMMANDS        ( (CONFIG_CMD_DFL & \
+                (~CFG_CMD_RTC) & ~(CFG_CMD_I2C)) | \
+                CFG_CMD_IRQ | \
+                CFG_CMD_PCI | \
+                CFG_CMD_DHCP | \
+                CFG_CMD_ASKENV | \
+                CFG_CMD_ELF  | \
+                CFG_CMD_PING | \
+                CFG_CMD_MVENV  \
+                               )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG          /* watchdog disabled        */
+
+#define CONFIG_SYS_CLK_FREQ 30000000
+
+#define CONFIG_SPD_EEPROM      1       /* use SPD EEPROM for setup    */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP            /* undef to save memory     */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CBSIZE  1024        /* Console I/O Buffer Size  */
+#else
+#define CFG_CBSIZE  256     /* Console I/O Buffer Size  */
+#endif
+/* usually: (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) */
+#define CFG_PBSIZE (CFG_CBSIZE+4+16) /* Print Buffer Size */
+#define CFG_MAXARGS 16      /* max number of command args   */
+#define CFG_BARGSIZE    CFG_CBSIZE  /* Boot Argument Buffer Size    */
+
+#define CFG_ALT_MEMTEST     1
+#define CFG_MEMTEST_START   0x00400000  /* memtest works on */
+#define CFG_MEMTEST_END     0x01000000  /* 4 ... 16 MB in DRAM  */
+
+/*
+ * If CFG_EXT_SERIAL_CLOCK, then the UART divisor is 1.
+ * If CFG_405_UART_ERRATA_59, then UART divisor is 31.
+ * Otherwise, UART divisor is determined by CPU Clock and CFG_BASE_BAUD value.
+ * The Linux BASE_BAUD define should match this configuration.
+ *    baseBaud = cpuClock/(uartDivisor*16)
+ * If CFG_405_UART_ERRATA_59 and 200MHz CPU clock,
+ * set Linux BASE_BAUD to 403200.
+ */
+#undef  CFG_EXT_SERIAL_CLOCK           /* external serial clock */
+#undef  CFG_405_UART_ERRATA_59         /* 405GP/CR Rev. D silicon */
+
+#define CFG_NS16550_CLK     40000000
+#define CFG_DUART_CHAN      0
+#define CFG_NS16550_COM1    (0x4C000000 + 0x1000)
+#define CFG_NS16550_COM2    (0x4C800000 + 0x1000)
+#define CFG_NS16550_REG_SIZE 4
+#define CFG_NS16550 1
+#define CFG_INIT_CHAN1   1
+#define CFG_INIT_CHAN2   0
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE  \
+    {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
+
+#define CFG_LOAD_ADDR       0x00100000  /* default load address */
+#define CFG_EXTBDINFO       1   /* To use extended board_into (bd_t) */
+
+#define CFG_HZ      1000        /* decrementer freq: 1 ms ticks */
+
+
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE      0x00000000
+#define CFG_FLASH_BASE      0x20000000
+#define CFG_MONITOR_BASE    TEXT_BASE
+#define CFG_MONITOR_LEN     (192 * 1024)    /* Reserve 196 kB for Monitor   */
+#define CFG_MALLOC_LEN      (128 * 1024)    /* Reserve 128 kB for malloc()  */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ       (8 << 20)   /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_FLASH_CFI       1
+#define CFG_PROGFLASH_BASE  CFG_FLASH_BASE
+#define CFG_CONFFLASH_BASE  0x24000000
+
+#define CFG_MAX_FLASH_BANKS 2   /* max number of memory banks       */
+#define CFG_MAX_FLASH_SECT  256 /* max number of sectors on one chip    */
+
+#define CFG_FLASH_ERASE_TOUT    120000  /* Timeout for Flash Erase (in ms)  */
+#define CFG_FLASH_WRITE_TOUT    500 /* Timeout for Flash Write (in ms)  */
+
+#define CFG_FLASH_PROTECTION    1   /* use hardware protection      */
+
+/* BEG ENVIRONNEMENT FLASH */
+#ifdef CFG_ENV_IS_IN_FLASH
+#define CFG_ENV_OFFSET      0x00040000 /* Offset of Environment Sector  */
+#define CFG_ENV_SIZE        0x1000  /* Total Size of Environment Sector */
+#define CFG_ENV_SECT_SIZE   0x20000 /* see README - env sector total size   */
+#endif
+/* END ENVIRONNEMENT FLASH */
+/*-----------------------------------------------------------------------
+ * NVRAM organization
+ */
+#define CFG_NVRAM_BASE_ADDR 0xf0000000  /* NVRAM base address   */
+#define CFG_NVRAM_SIZE      0x1ff8      /* NVRAM size   */
+
+#ifdef CFG_ENV_IS_IN_NVRAM
+#define CFG_ENV_SIZE        0x1000      /* Size of Environment vars */
+#define CFG_ENV_ADDR        \
+    (CFG_NVRAM_BASE_ADDR+CFG_NVRAM_SIZE-CFG_ENV_SIZE)   /* Env  */
+#endif
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE     16384
+#define CFG_CACHELINE_SIZE  32
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT 5   /* log base 2 of the above value    */
+#endif
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0/1 and OR0/1 (FLASH)
+ */
+
+#define FLASH_BASE0_PRELIM  CFG_FLASH_BASE  /* FLASH bank #0    */
+#define FLASH_BASE1_PRELIM  0       /* FLASH bank #1    */
+
+
+/* Configuration Port location */
+#define CONFIG_PORT_ADDR    0xF0000500
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+#define CFG_INIT_RAM_ADDR       0x400000  /* inside of SDRAM                     */
+#define CFG_INIT_RAM_END        0x2000  /* End of used area in RAM             */
+#define CFG_GBL_DATA_SIZE      128  /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET    (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET      CFG_GBL_DATA_OFFSET
+
+/*-----------------------------------------------------------------------
+ * Definitions for Serial Presence Detect EEPROM address
+ * (to get SDRAM settings)
+ */
+#define SPD_EEPROM_ADDRESS      0x50
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD   0x01        /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM   0x02        /* Software reboot          */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE    230400  /* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX   2   /* which serial port to use */
+#endif
+
+/* JFFS2 stuff */
+
+#define CFG_JFFS2_FIRST_BANK 0
+#define CFG_JFFS2_NUM_BANKS 1
+#define CFG_JFFS2_FIRST_SECTOR 1
+
+#define CONFIG_NET_MULTI
+#define CONFIG_E1000
+
+#define CFG_ETH_DEV_FN     0x0800
+#define CFG_ETH_IOBASE     0x31000000
+#define CFG_ETH_MEMBASE    0x32000000
+
+#endif  /* __CONFIG_H */
diff --git a/net/eth.c b/net/eth.c
index aa45b75..fe1edd1 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -125,7 +125,7 @@
 #ifdef CONFIG_DB64460
 	mv6446x_eth_initialize(bis);
 #endif
-#if defined(CONFIG_4xx) && !defined(CONFIG_IOP480)
+#if defined(CONFIG_4xx) && !defined(CONFIG_IOP480) && !defined(CONFIG_AP1000)
 	ppc_4xx_eth_initialize(bis);
 #endif
 #ifdef CONFIG_INCA_IP_SWITCH