From: wdenk Date: Wed, 21 Aug 2002 23:00:30 +0000 (+0000) Subject: Patch by Keith Outwate, 21 Aug 2002: X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=53128b04a78b9f3e8e13449ed6a4b214785453db;p=users%2Frw%2Fppcboot.git Patch by Keith Outwate, 21 Aug 2002: - fix/add debug messages in soft_i2c.c - added better memory test (optional) - added support for 3rd status LED - Date & Time support (no alarms) for Dallas Semiconductor (now Maxim) DS1337 Real Time Clock - README fixes / extensions - FPGA device configuration driver (Rich Ireland) --- diff --git a/CHANGELOG b/CHANGELOG index c6d2583..bdc0d0d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,14 @@ Modifications for 1.2.0: For details about the current modifications, please see README-WIP +* Patch by Keith Outwate, 21 Aug 2002: + - fix/add debug messages in soft_i2c.c + - added better memory test (optional) + - added support for 3rd status LED + - Date & Time support (no alarms) for + Dallas Semiconductor (now Maxim) DS1337 Real Time Clock + - README fixes / extensions + - FPGA device configuration driver (Rich Ireland) * Patch by Scott McNutt,, 14 Aug 2002: IBM 440GP Ethernet support diff --git a/CREDITS b/CREDITS index f64d152..7431148 100644 --- a/CREDITS +++ b/CREDITS @@ -36,7 +36,7 @@ D: PCMCIA, Ethernet, TFTP N: Jerry van Baren E: -D: BedBug port to 603e core (MPC82xx) +D: BedBug port to 603e core (MPC82xx). Code for enhanced memory test. N: Raphael Bossek E: raphael.bossek@solutions4linux.de @@ -122,6 +122,10 @@ H: Stuart Hughes E: stuarth@lineo.com D: Port to MPC8260ADS board +H: Rich Ireland +E: r.ireland@computer.org +D: FPGA device configuration driver + N: Murray Jensen E: Murray.Jensen@cmst.csiro.au D: Initial 8260 support; GDB support diff --git a/README b/README index f072820..bde093d 100644 --- a/README +++ b/README @@ -792,6 +792,54 @@ The following options need to be configured: Time to wait after FPGA configuration. The default is 200 mS. +- FPGA Support: CONFIG_FPGA_COUNT + + Specify the number of FPGA devices to support. + + CONFIG_FPGA + + Used to specify the types of FPGA devices. For example, + #define CONFIG_FPGA CFG_XILINX_VIRTEX2 + + CFG_FPGA_PROG_FEEDBACK + + Enable printing of hash marks during FPGA configuration. + + CFG_FPGA_CHECK_BUSY + + Enable checks on FPGA configuration interface busy status + by the configuration function. This option will require + a board or device specific function to be written. + + CONFIG_FPGA_DELAY + + If defined, a function that provides delays in the FPGA + configuration driver. + + CFG_FPGA_CHECK_CTRLC + Allow Control-C to interrupt FPGA configuration + + CFG_FPGA_CHECK_ERROR + + Check for configuration errors during FPGA bitfile loading. + For example, abort during Virtex II configuration if the + INIT_B line goes low (which indicated a CRC error). + + CFG_FPGA_WAIT_INIT + + Maximum time to wait for the INIT_B line to deassert after + PROB_B has been deasserted during a Virtex II FPGA + configuration sequence. The default time is 500 mS. + + CFG_FPGA_WAIT_BUSY + + Maximum time to wait for BUSY to deassert during Virtex II + FPGA configuration. The default is 5 mS. + + CFG_FPGA_WAIT_CONFIG + + Time to wait after FPGA configuration. The default is 200 mS. + - Configuration Management: CONFIG_IDENT_STRING @@ -1224,6 +1272,26 @@ to save the current settings. - CFG_EEPROM_SIZE: The size in bytes of the EEPROM device. + - CFG_I2C_EEPROM_ADDR: + If defined, specified the chip address of the EEPROM device. + The default address is zero. + + - CFG_EEPROM_PAGE_WRITE_BITS: + If defined, the number of bits used to address bytes in a + single page in the EEPROM device. A 64 byte page, for example + would require six bits. + + - CFG_EEPROM_PAGE_WRITE_DELAY_MS: + If defined, the number of milliseconds to delay between + page writes. The default is zero milliseconds. + + - CFG_I2C_EEPROM_ADDR_LEN: + The length in bytes of the EEPROM memory array address. Note + that this is NOT the chip address length! + + - CFG_EEPROM_SIZE: + The size in bytes of the EEPROM device. + - CFG_SPI_INIT_OFFSET Defines offset to the initial SPI buffer area in DPRAM. The diff --git a/board/dnp1110/dnp1110.c b/board/dnp1110/dnp1110.c index 588febd..e551b7b 100644 --- a/board/dnp1110/dnp1110.c +++ b/board/dnp1110/dnp1110.c @@ -31,23 +31,24 @@ * Miscelaneous platform dependent initialisations */ -int board_init(bd_t *bd) +int board_init (gd_t *gd) { - /* memory and cpu-speed are setup before relocation */ - /* so we do _nothing_ here */ + /* memory and cpu-speed are setup before relocation */ + /* so we do _nothing_ here */ - /* arch number of DNP1110-Board */ - bd->bi_arch_number = 255; + /* arch number of DNP1110-Board */ + bd->bi_arch_number = 255; - /* adress of boot parameters */ - bd->bi_boot_params = 0xc0000100; + /* adress of boot parameters */ + bd->bi_boot_params = 0xc0000100; - return 1; + return 0; } -int dram_init(bd_t *bd) +int dram_init (gd_t *gd) { - bd->bi_dram[0].start = PHYS_SDRAM_1; - bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - return PHYS_SDRAM_1_SIZE; + bd->bi_dram[0].start = PHYS_SDRAM_1; + bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + return PHYS_SDRAM_1_SIZE; } diff --git a/board/ep7312/ep7312.c b/board/ep7312/ep7312.c index 2611190..7ea2a53 100644 --- a/board/ep7312/ep7312.c +++ b/board/ep7312/ep7312.c @@ -32,24 +32,24 @@ * Miscelaneous platform dependent initialisations */ -int board_init(bd_t *bd) +int board_init (gd_t *gd) { - /* Activate LED flasher */ - IO_LEDFLSH = 0x40; + /* Activate LED flasher */ + IO_LEDFLSH = 0x40; - /* arch number MACH_TYPE_EDB7312 */ - bd->bi_arch_number = 131; + /* arch number MACH_TYPE_EDB7312 */ + bd->bi_arch_number = 131; - /* location of boot parameters */ - bd->bi_boot_params = 0xc0020100; + /* location of boot parameters */ + bd->bi_boot_params = 0xc0020100; - return 1; + return 0; } -int dram_init(bd_t *bd) +int dram_init (gd_t *gd) { - bd->bi_dram[0].start = PHYS_SDRAM_1; - bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + bd->bi_dram[0].start = PHYS_SDRAM_1; + bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - return PHYS_SDRAM_1_SIZE; + return PHYS_SDRAM_1_SIZE; } diff --git a/board/impa7/impa7.c b/board/impa7/impa7.c index 6f8f74f..792ec07 100644 --- a/board/impa7/impa7.c +++ b/board/impa7/impa7.c @@ -32,26 +32,26 @@ * Miscelaneous platform dependent initialisations */ -int board_init(bd_t *bd) +int board_init (gd_t *gd) { - /* Activate LED flasher */ - IO_LEDFLSH = 0x40; + /* Activate LED flasher */ + IO_LEDFLSH = 0x40; - /* arch number of EP7111 */ - bd->bi_arch_number = 50; + /* arch number of EP7111 */ + bd->bi_arch_number = 50; - /* location of boot parameters for EP7111 */ - bd->bi_boot_params = 0xc0020100; + /* location of boot parameters for EP7111 */ + bd->bi_boot_params = 0xc0020100; - return 1; + return 0; } -int dram_init(bd_t *bd) +int dram_init (gd_t *gd) { - bd->bi_dram[0].start = PHYS_SDRAM_1; - bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - bd->bi_dram[1].start = PHYS_SDRAM_2; - bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; - - return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE; + bd->bi_dram[0].start = PHYS_SDRAM_1; + bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + bd->bi_dram[1].start = PHYS_SDRAM_2; + bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; + + return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE; } diff --git a/board/lart/lart.c b/board/lart/lart.c index d1d874b..30845ad 100644 --- a/board/lart/lart.c +++ b/board/lart/lart.c @@ -31,29 +31,33 @@ * Miscelaneous platform dependent initialisations */ -int board_init(bd_t *bd) +int board_init (gd_t *gd) { - /* memory and cpu-speed are setup before relocation */ - /* so we do _nothing_ here */ + /* memory and cpu-speed are setup before relocation */ + /* so we do _nothing_ here */ - /* arch number of LART-Board */ - bd->bi_arch_number = 27; + /* arch number of LART-Board */ + bd->bi_arch_number = 27; - /* adress of boot parameters */ - bd->bi_boot_params = 0xc0000100; + /* adress of boot parameters */ + bd->bi_boot_params = 0xc0000100; - return 1; + return 0; } -int dram_init(bd_t *bd) +int dram_init (gd_t *gd) { - bd->bi_dram[0].start = PHYS_SDRAM_1; - bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - bd->bi_dram[1].start = PHYS_SDRAM_2; - bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; - bd->bi_dram[2].start = PHYS_SDRAM_3; - bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE; - bd->bi_dram[3].start = PHYS_SDRAM_4; - bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE; - return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE + PHYS_SDRAM_3_SIZE + PHYS_SDRAM_4_SIZE; + bd->bi_dram[0].start = PHYS_SDRAM_1; + bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + bd->bi_dram[1].start = PHYS_SDRAM_2; + bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; + bd->bi_dram[2].start = PHYS_SDRAM_3; + bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE; + bd->bi_dram[3].start = PHYS_SDRAM_4; + bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE; + + return (PHYS_SDRAM_1_SIZE + + PHYS_SDRAM_2_SIZE + + PHYS_SDRAM_3_SIZE + + PHYS_SDRAM_4_SIZE ); } diff --git a/board/shannon/shannon.c b/board/shannon/shannon.c index e69656b..1a23ec4 100644 --- a/board/shannon/shannon.c +++ b/board/shannon/shannon.c @@ -31,13 +31,13 @@ * Miscelaneous platform dependent initialisations */ -int board_init(bd_t *bd) +int board_init (gd_t *gd) { - /* memory and cpu-speed are setup before relocation */ - /* but if we use InfernoLoader, we must do some inits here */ + /* memory and cpu-speed are setup before relocation */ + /* but if we use InfernoLoader, we must do some inits here */ - #ifdef CONFIG_INFERNO - { +#ifdef CONFIG_INFERNO + { unsigned long temp; __asm__ __volatile__(/* disable MMU, enable icache */ "mrc p15, 0, %0, c1, c0\n" @@ -57,43 +57,45 @@ int board_init(bd_t *bd) temp = 0xa0000018; *(unsigned long *)temp = 0x00060006; - } - #endif /* CONFIG_INIT_CRITICAL */ + } +#endif /* CONFIG_INIT_CRITICAL */ - /* arch number for shannon */ - bd->bi_arch_number = 97; + /* arch number for shannon */ + bd->bi_arch_number = 97; - /* adress of boot parameters */ - bd->bi_boot_params = 0xc0000100; + /* adress of boot parameters */ + bd->bi_boot_params = 0xc0000100; - return 1; + return 0; } -int dram_init(bd_t *bd) +int dram_init (gd_t * gd) { - #ifdef PHYS_SDRAM_1 - bd->bi_dram[0].start = PHYS_SDRAM_1; - bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - #endif +#ifdef PHYS_SDRAM_1 + bd->bi_dram[0].start = PHYS_SDRAM_1; + bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; +#endif - #ifdef PHYS_SDRAM_2 - bd->bi_dram[1].start = PHYS_SDRAM_2; - bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; - #endif +#ifdef PHYS_SDRAM_2 + bd->bi_dram[1].start = PHYS_SDRAM_2; + bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; +#endif - #ifdef PHYS_SDRAM_3 - bd->bi_dram[2].start = PHYS_SDRAM_3; - bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE; - #endif +#ifdef PHYS_SDRAM_3 + bd->bi_dram[2].start = PHYS_SDRAM_3; + bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE; +#endif - #ifdef PHYS_SDRAM_4 - bd->bi_dram[3].start = PHYS_SDRAM_4; - bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE; - #endif +#ifdef PHYS_SDRAM_4 + bd->bi_dram[3].start = PHYS_SDRAM_4; + bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE; +#endif - return PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE - #ifdef PHYS_SDRAM_4 - + PHYS_SDRAM_3_SIZE + PHYS_SDRAM_4_SIZE - #endif - ; + return ( PHYS_SDRAM_1_SIZE + + PHYS_SDRAM_2_SIZE +#ifdef PHYS_SDRAM_4 + + PHYS_SDRAM_3_SIZE + + PHYS_SDRAM_4_SIZE +#endif + ); } diff --git a/board/smdk2410/smdk2410.c b/board/smdk2410/smdk2410.c index 5944d94..2d12440 100644 --- a/board/smdk2410/smdk2410.c +++ b/board/smdk2410/smdk2410.c @@ -32,89 +32,85 @@ #define FCLK_SPEED 1 -#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */ - #define M_MDIV 0xC3 - #define M_PDIV 0x4 - #define M_SDIV 0x1 -#elif FCLK_SPEED==1 /* Fout = 202.8MHz */ - #define M_MDIV 0xA1 - #define M_PDIV 0x3 - #define M_SDIV 0x1 +#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */ +#define M_MDIV 0xC3 +#define M_PDIV 0x4 +#define M_SDIV 0x1 +#elif FCLK_SPEED==1 /* Fout = 202.8MHz */ +#define M_MDIV 0xA1 +#define M_PDIV 0x3 +#define M_SDIV 0x1 #endif #define USB_CLOCK 1 #if USB_CLOCK==0 - #define U_M_MDIV 0xA1 - #define U_M_PDIV 0x3 - #define U_M_SDIV 0x1 +#define U_M_MDIV 0xA1 +#define U_M_PDIV 0x3 +#define U_M_SDIV 0x1 #elif USB_CLOCK==1 - #define U_M_MDIV 0x48 - #define U_M_PDIV 0x3 - #define U_M_SDIV 0x2 +#define U_M_MDIV 0x48 +#define U_M_PDIV 0x3 +#define U_M_SDIV 0x2 #endif -static inline -void delay(unsigned long loops) +static inline void delay (unsigned long loops) { - __asm__ volatile ( - "1:\n" - "subs %0, %1, #1\n" - "bne 1b" - : "=r" (loops) : "0" (loops)); + __asm__ volatile ("1:\n" + "subs %0, %1, #1\n" + "bne 1b":"=r" (loops):"0" (loops)); } /* * Miscellaneous platform dependent initialisations */ -int board_init(bd_t *bd) +int board_init (gd_t *gd) { - /* to reduce PLL lock time, adjust the LOCKTIME register */ - rLOCKTIME = 0xFFFFFF; - - /* configure MPLL */ - rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV); - - /* some delay between MPLL and UPLL */ - delay(4000); - - /* configure UPLL */ - rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV); - - /* some delay between MPLL and UPLL */ - delay(8000); - - /* set up the I/O ports */ - rGPACON = 0x007FFFFF; - rGPBCON = 0x00044555; - rGPBUP = 0x000007FF; - rGPCCON = 0xAAAAAAAA; - rGPCUP = 0x0000FFFF; - rGPDCON = 0xAAAAAAAA; - rGPDUP = 0x0000FFFF; - rGPECON = 0xAAAAAAAA; - rGPEUP = 0x0000FFFF; - rGPFCON = 0x000055AA; - rGPFUP = 0x000000FF; - rGPGCON = 0xFF95FFBA; - rGPGUP = 0x0000FFFF; - rGPHCON = 0x002AFAAA; - rGPHUP = 0x000007FF; - - /* arch number of SMDK2410-Board */ - bd->bi_arch_number = 193; - - /* adress of boot parameters */ - bd->bi_boot_params = 0x30000100; - - return 1; + /* to reduce PLL lock time, adjust the LOCKTIME register */ + rLOCKTIME = 0xFFFFFF; + + /* configure MPLL */ + rMPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV); + + /* some delay between MPLL and UPLL */ + delay (4000); + + /* configure UPLL */ + rUPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV); + + /* some delay between MPLL and UPLL */ + delay (8000); + + /* set up the I/O ports */ + rGPACON = 0x007FFFFF; + rGPBCON = 0x00044555; + rGPBUP = 0x000007FF; + rGPCCON = 0xAAAAAAAA; + rGPCUP = 0x0000FFFF; + rGPDCON = 0xAAAAAAAA; + rGPDUP = 0x0000FFFF; + rGPECON = 0xAAAAAAAA; + rGPEUP = 0x0000FFFF; + rGPFCON = 0x000055AA; + rGPFUP = 0x000000FF; + rGPGCON = 0xFF95FFBA; + rGPGUP = 0x0000FFFF; + rGPHCON = 0x002AFAAA; + rGPHUP = 0x000007FF; + + /* arch number of SMDK2410-Board */ + bd->bi_arch_number = 193; + + /* adress of boot parameters */ + bd->bi_boot_params = 0x30000100; + + return 0; } -int dram_init(bd_t *bd) +int dram_init (gd_t *gd) { - bd->bi_dram[0].start = PHYS_SDRAM_1; - bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - return PHYS_SDRAM_1_SIZE; + bd->bi_dram[0].start = PHYS_SDRAM_1; + bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + return PHYS_SDRAM_1_SIZE; } - diff --git a/common/Makefile b/common/Makefile index a29a891..e0a9cf5 100644 --- a/common/Makefile +++ b/common/Makefile @@ -26,18 +26,18 @@ include $(TOPDIR)/config.mk LIB = libcommon.a AOBJS = -COBJS = main.o command.o environment.o bedbug.o \ - cmd_autoscript.o cmd_bedbug.o cmd_boot.o \ - cmd_bootm.o cmd_cache.o cmd_console.o cmd_date.o \ - cmd_dcr.o cmd_doc.o cmd_dtt.o cmd_eeprom.o cmd_elf.o \ - cmd_fdc.o cmd_flash.o cmd_i2c.o cmd_ide.o \ - cmd_immap.o cmd_jffs2.o cmd_mem.o cmd_mii.o \ - cmd_misc.o cmd_net.o cmd_nvedit.o cmd_pcmcia.o \ - cmd_reginfo.o cmd_scsi.o cmd_usb.o cmd_pci.o \ - console.o devices.o dlmalloc.o docecc.o \ - flash.o hush.o kgdb.o lists.o \ - miiphybb.o miiphyutil.o s_record.o \ - usb.o usb_kbd.o usb_storage.o soft_i2c.o +COBJS = main.o altera.o command.o environment.o bedbug.o \ + cmd_autoscript.o cmd_bedbug.o cmd_boot.o cmd_bootm.o \ + cmd_cache.o cmd_console.o cmd_date.o cmd_dcr.o cmd_doc.o \ + cmd_dtt.o cmd_eeprom.o cmd_elf.o cmd_fdc.o cmd_flash.o \ + cmd_fpga.o cmd_i2c.o cmd_ide.o cmd_immap.o cmd_jffs2.o \ + cmd_mem.o cmd_mii.o cmd_misc.o cmd_net.o cmd_nvedit.o \ + cmd_pcmcia.o cmd_reginfo.o cmd_scsi.o cmd_usb.o cmd_pci.o \ + console.o devices.o dlmalloc.o docecc.o flash.o fpga.o \ + hush.o kgdb.o lists.o miiphybb.o miiphyutil.o s_record.o \ + soft_i2c.o spartan2.o usb.o usb_kbd.o usb_storage.o \ + virtex2.o xilinx.o + # Temporary hack to get ARM working quickly ifeq ($(ARCH),ppc) COBJS += cmd_nvedit.o diff --git a/common/altera.c b/common/altera.c new file mode 100644 index 0000000..beb0147 --- /dev/null +++ b/common/altera.c @@ -0,0 +1,73 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 + * + */ + +/* + * Note that this is just boilerplate - there is no Altera support yet. + */ + + +/* + * Altera FPGA support + */ +#include +#include /* Generic FPGA support */ +#include /* Altera specific stuff */ + +#if 0 +#define FPGA_DEBUG +#endif + +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#if (CONFIG_FPGA & CFG_FPGA_ALTERA) + +/* ------------------------------------------------------------------------- */ +int altera_load( Altera_desc *desc, void *buf, size_t bsize ) +{ + printf( "No support for Altera devices yet.\n" ); + return FPGA_FAIL; +} + +int altera_dump( Altera_desc *desc, void *buf, size_t bsize ) +{ + printf( "No support for Altera devices yet.\n" ); + return FPGA_FAIL; +} + +int altera_info( Altera_desc *desc ) +{ + printf( "No support for Altera devices yet.\n" ); + return FPGA_FAIL; +} + +/* ------------------------------------------------------------------------- */ + + +/* ------------------------------------------------------------------------- */ + +#endif /* CONFIG_FPGA & CFG_FPGA_ALTERA */ diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c new file mode 100644 index 0000000..3d8c79e --- /dev/null +++ b/common/cmd_fpga.c @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2000, 2001 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 + * + */ + +/* + * FPGA support + */ +#include +#include +#include +#include +#if (CONFIG_COMMANDS & CFG_CMD_NET) +#include +#endif + +#if 0 +#define FPGA_DEBUG +#endif + +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#if defined (CONFIG_FPGA) && ( CONFIG_COMMANDS & CFG_CMD_FPGA ) + +/* Local functions */ +static void fpga_usage ( cmd_tbl_t *cmdtp ); +static int fpga_get_op( char *opstr ); + +/* Local defines */ +#define FPGA_NONE -1 +#define FPGA_INFO 0 +#define FPGA_LOAD 1 +#define FPGA_DUMP 3 + +/* ------------------------------------------------------------------------- */ +/* command form: + * fpga + * where op is 'load', 'dump', or 'info' + * If there is no device number field, the fpga environment variable is used. + * If there is no data addr field, the fpgadata environment variable is used. + * The info command requires no data address field. + */ +int +do_fpga (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]) +{ + int op, dev = FPGA_INVALID_DEVICE; + size_t data_size = 0; + void *fpga_data = NULL; + char *devstr = getenv("fpga"); + char *datastr = getenv("fpgadata"); + + if ( devstr ) dev = (int)simple_strtoul( devstr, NULL, 16 ); + if ( datastr ) fpga_data = (void *)simple_strtoul( datastr, NULL, 16 ); + + switch ( argc ) + { + case 5: /* fpga */ + data_size = simple_strtoul( argv[4], NULL, 16 ); + case 4: /* fpga */ + fpga_data = (void *)simple_strtoul( argv[3], NULL, 16 ); + PRINTF(__FUNCTION__": fpga_data = 0x%x\n", (uint)fpga_data ); + case 3: /* fpga */ + dev = (int)simple_strtoul( argv[2], NULL, 16 ); + PRINTF(__FUNCTION__": device = %d\n", dev ); + /* FIXME - this is a really weak test */ + if (( argc == 3 ) && ( dev > fpga_count() )) { /* must be buffer ptr */ + PRINTF(__FUNCTION__": Assuming buffer pointer in arg 3\n"); + fpga_data = (void *)dev; + PRINTF(__FUNCTION__": fpga_data = 0x%x\n", (uint)fpga_data ); + dev = FPGA_INVALID_DEVICE; /* reset device num */ + } + case 2: /* fpga */ + op = (int)fpga_get_op( argv[1] ); + break; + default: + PRINTF(__FUNCTION__": Too many or too few args (%d)\n", argc ); + op = FPGA_NONE; /* force usage display */ + break; + } + + switch ( op ) { + case FPGA_NONE: + fpga_usage( cmdtp ); + break; + + case FPGA_INFO: + fpga_info( dev ); + break; + + case FPGA_LOAD: + fpga_load( dev, fpga_data, data_size ); + break; + + case FPGA_DUMP: + fpga_dump( dev, fpga_data, data_size ); + break; + + default: + printf( "Unknown operation.\n" ); + fpga_usage( cmdtp ); + break; + } + return 0; +} + +static void fpga_usage ( cmd_tbl_t *cmdtp ) +{ + printf( "Usage:\n%s\n", cmdtp->usage ); +} + +/* + * Map op to supported operations. We don't use a table since we + * would just have to relocate it from flash anyway. + */ +static int fpga_get_op( char *opstr ) +{ + int op = FPGA_NONE; + + if (!strcmp ("info", opstr)) { + op = FPGA_INFO; + } + else if (!strcmp ("load", opstr)) { + op = FPGA_LOAD; + } + else if (!strcmp ("dump", opstr)) { + op = FPGA_DUMP; + } + + if ( op == FPGA_NONE ) { + printf ("Unknown fpga operation \"%s\"\n", opstr); + } + return op; +} + +#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */ diff --git a/common/cmd_mem.c b/common/cmd_mem.c index e395e25..497dd79 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -39,11 +39,11 @@ int cmd_get_data_size(char* arg, int default_size) int len = strlen(arg); if (len > 2 && arg[len-2] == '.') { switch(arg[len-1]) { - case 'b': - return 1; - case 'w': + case 'b': + return 1; + case 'w': return 2; - case 'l': + case 'l': return 4; } } @@ -52,6 +52,13 @@ int cmd_get_data_size(char* arg, int default_size) #endif #if (CONFIG_COMMANDS & CFG_CMD_MEMORY) + +#ifdef CMD_MEM_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + static int mod_mem(cmd_tbl_t *, int, int, int, char *[]); /* Display values from last command. @@ -157,7 +164,7 @@ int do_mem_md ( cmd_tbl_t *cmdtp, gd_t *gd, int do_mem_mm ( cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]) { - return mod_mem (cmdtp, 1, flag, argc, argv); + return mod_mem (cmdtp, 1, flag, argc, argv); } int do_mem_nm ( cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]) @@ -417,16 +424,44 @@ int do_mem_loop (cmd_tbl_t *cmdtp, gd_t *gd, } } -/* Just a quickie to walk through some memory. +/* + * Perform a memory test. A more complete alternative test can be + * configured using CFG_ALT_MEMTEST. The complete test loops until + * interrupted by ctrl-c or by a failure of one of the sub-tests. */ - -int do_mem_mtest (cmd_tbl_t *cmdtp, gd_t *gd, - int flag, int argc, char *argv[]) +int do_mem_mtest (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]) { - ulong *addr, *start, *end; + vu_long *addr, *start, *end; ulong val; + ulong readback; + +#if defined(CFG_ALT_MEMTEST) + vu_long addr_mask; + vu_long offset; + vu_long test_offset; + vu_long pattern; + vu_long temp; + vu_long anti_pattern; + vu_long num_words; + vu_long *dummy = NULL; + int j; + int iterations = 1; + + static const ulong bitpattern[] = { + 0x00000001, /* single bit */ + 0x00000003, /* two adjacent bits */ + 0x00000007, /* three adjacent bits */ + 0x0000000F, /* four adjacent bits */ + 0x00000005, /* two non-adjacent bits */ + 0x00000015, /* three non-adjacent bits */ + 0x00000055, /* four non-adjacent bits */ + 0xaaaaaaaa, /* alternating 1/0 */ + }; +#else + ulong incr; ulong pattern; int rcode = 0; +#endif if (argc > 1) { start = (ulong *)simple_strtoul(argv[1], NULL, 16); @@ -446,8 +481,207 @@ int do_mem_mtest (cmd_tbl_t *cmdtp, gd_t *gd, pattern = 0; } +#if defined(CFG_ALT_MEMTEST) printf ("Testing %08x ... %08x:\n", (uint)start, (uint)end); + PRINTF("%s:%d: start 0x%p end 0x%p\n", + __FUNCTION__, __LINE__, start, end); + + for (;;) { + if (ctrlc()) { + putc ('\n'); + return 1; + } + + printf("Iteration: %6d\r", iterations); + PRINTF("Iteration: %6d\n", iterations); + iterations++; + + /* + * Data line test: write a pattern to the first + * location, write the 1's complement to a 'parking' + * address (changes the state of the data bus so a + * floating bus doen't give a false OK), and then + * read the value back. Note that we read it back + * into a variable because the next time we read it, + * it might be right (been there, tough to explain to + * the quality guys why it prints a failure when the + * "is" and "should be" are obviously the same in the + * error message). + * + * Rather than exhaustively testing, we test some + * patterns by shifting '1' bits through a field of + * '0's and '0' bits through a field of '1's (i.e. + * pattern and ~pattern). + */ + addr = start; + for (j = 0; j < sizeof(bitpattern)/sizeof(bitpattern[0]); j++) { + val = bitpattern[j]; + for(; val != 0; val <<= 1) { + *addr = val; + *dummy = ~val; /* clear the test data off of the bus */ + readback = *addr; + if(readback != val) { + printf ("FAILURE (data line): " + "expected %08lx, actual %08lx\n", + val, readback); + } + *addr = ~val; + *dummy = val; + readback = *addr; + if(readback != ~val) { + printf ("FAILURE (data line): " + "Is %08lx, should be %08lx\n", + val, readback); + } + } + } + + /* + * Based on code whose Original Author and Copyright + * information follows: Copyright (c) 1998 by Michael + * Barr. This software is placed into the public + * domain and may be used for any purpose. However, + * this notice must not be changed or removed and no + * warranty is either expressed or implied by its + * publication or distribution. + */ + + /* + * Address line test + * + * Description: Test the address bus wiring in a + * memory region by performing a walking + * 1's test on the relevant bits of the + * address and checking for aliasing. + * This test will find single-bit + * address failures such as stuck -high, + * stuck-low, and shorted pins. The base + * address and size of the region are + * selected by the caller. + * + * Notes: For best results, the selected base + * address should have enough LSB 0's to + * guarantee single address bit changes. + * For example, to test a 64-Kbyte + * region, select a base address on a + * 64-Kbyte boundary. Also, select the + * region size as a power-of-two if at + * all possible. + * + * Returns: 0 if the test succeeds, 1 if the test fails. + * + * ## NOTE ## Be sure to specify start and end + * addresses such that addr_mask has + * lots of bits set. For example an + * address range of 01000000 02000000 is + * bad while a range of 01000000 + * 01ffffff is perfect. + */ + addr_mask = ((ulong)end - (ulong)start)/sizeof(vu_long); + pattern = (vu_long) 0xaaaaaaaa; + anti_pattern = (vu_long) 0x55555555; + + PRINTF("%s:%d: addr mask = 0x%.8lx\n", + __FUNCTION__, __LINE__, + addr_mask); + /* + * Write the default pattern at each of the + * power-of-two offsets. + */ + for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) { + start[offset] = pattern; + } + + /* + * Check for address bits stuck high. + */ + test_offset = 0; + start[test_offset] = anti_pattern; + + for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) { + temp = start[offset]; + if (temp != pattern) { + printf ("\nFAILURE: Address bit stuck high @ 0x%.8lx:" + " expected 0x%.8lx, actual 0x%.8lx\n", + (ulong)&start[offset], pattern, temp); + return 1; + } + } + start[test_offset] = pattern; + /* + * Check for addr bits stuck low or shorted. + */ + for (test_offset = 1; (test_offset & addr_mask) != 0; test_offset <<= 1) { + start[test_offset] = anti_pattern; + + for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) { + temp = start[offset]; + if ((temp != pattern) && (offset != test_offset)) { + printf ("\nFAILURE: Address bit stuck low or shorted @" + " 0x%.8lx: expected 0x%.8lx, actual 0x%.8lx\n", + (ulong)&start[offset], pattern, temp); + return 1; + } + } + start[test_offset] = pattern; + } + + /* + * Description: Test the integrity of a physical + * memory device by performing an + * increment/decrement test over the + * entire region. In the process every + * storage bit in the device is tested + * as a zero and a one. The base address + * and the size of the region are + * selected by the caller. + * + * Returns: 0 if the test succeeds, 1 if the test fails. + */ + num_words = ((ulong)end - (ulong)start)/sizeof(vu_long) + 1; + + /* + * Fill memory with a known pattern. + */ + for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { + start[offset] = pattern; + } + + /* + * Check each location and invert it for the second pass. + */ + for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { + temp = start[offset]; + if (temp != pattern) { + printf ("\nFAILURE (read/write) @ 0x%.8lx:" + " expected 0x%.8lx, actual 0x%.8lx)\n", + (ulong)&start[offset], pattern, temp); + return 1; + } + + anti_pattern = ~pattern; + start[offset] = anti_pattern; + } + + /* + * Check each location for the inverted pattern and zero it. + */ + for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { + anti_pattern = ~pattern; + temp = start[offset]; + if (temp != anti_pattern) { + printf ("\nFAILURE (read/write): @ 0x%.8lx:" + " expected 0x%.8lx, actual 0x%.8lx)\n", + (ulong)&start[offset], anti_pattern, temp); + return 1; + } + start[offset] = 0; + } + } + +#else /* The original, quickie test */ + incr = 1; for (;;) { if (ctrlc()) { putc ('\n'); @@ -460,31 +694,42 @@ int do_mem_mtest (cmd_tbl_t *cmdtp, gd_t *gd, pattern, ""); for (addr=start,val=pattern; addr /* 4xx DCR register access */ #include #include +#include #include /* board special functions */ @@ -246,6 +247,7 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_FLERASE CMD_TBL_FDC CMD_TBL_FLINFO + CMD_TBL_FPGA CMD_TBL_GETDCR CMD_TBL_GO CMD_TBL_HELP diff --git a/common/fpga.c b/common/fpga.c new file mode 100644 index 0000000..9c7f76c --- /dev/null +++ b/common/fpga.c @@ -0,0 +1,351 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 + * + */ + +/* + * Generic FPGA support + */ +#include /* core ppcboot definitions */ +#include /* xilinx specific definitions */ +#include /* altera specific definitions */ + +#if defined(CONFIG_FPGA) + +#if 0 +#define FPGA_DEBUG /* define FPGA_DEBUG to get debug messages */ +#endif + +/* Local definitions */ +#ifndef CONFIG_MAX_FPGA_DEVICES +#define CONFIG_MAX_FPGA_DEVICES 5 +#endif + +/* Enable/Disable debug console messages */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* Local static data */ +static ulong relocation_offset = 0; +static int next_desc = FPGA_INVALID_DEVICE; +static fpga_desc desc_table[CONFIG_MAX_FPGA_DEVICES]; + +/* Local static functions */ +static const fpga_desc * const fpga_get_desc( int devnum ); +static const fpga_desc * const fpga_validate( int devnum, void *buf, + size_t bsize, char *fn ); +static int fpga_dev_info( int devnum ); + + +/* ------------------------------------------------------------------------- */ + +/* fpga_no_sup + * 'no support' message function + */ +static void fpga_no_sup( char *fn, char *msg ) +{ + if ( fn && msg ) { + printf( "%s: No support for %s. CONFIG_FPGA defined as 0x%x.\n", + fn, msg, CONFIG_FPGA ); + } else if ( msg ) { + printf( "No support for %s. CONFIG_FPGA defined as 0x%x.\n", + msg, CONFIG_FPGA ); + } else { + printf( "No FPGA suport! CONFIG_FPGA defined as 0x%x.\n", + CONFIG_FPGA ); + } +} + + +/* fpga_get_desc + * map a device number to a descriptor + */ +static const fpga_desc * const fpga_get_desc( int devnum ) +{ + fpga_desc *desc = (fpga_desc * )NULL; + + if (( devnum >= 0 ) && (devnum < next_desc )) { + desc = &desc_table[devnum]; + PRINTF( "%s: found fpga descriptor #%d @ 0x%p\n", + __FUNCTION__, devnum, desc ); + } + + return desc; +} + + +/* fpga_validate + * generic parameter checking code + */ +static const fpga_desc * const fpga_validate( int devnum, void *buf, + size_t bsize, char *fn ) +{ + const fpga_desc * const desc = fpga_get_desc( devnum ); + + if ( !desc ) { + printf( "%s: Invalid device number %d\n", fn, devnum ); + } + + if ( !buf ) { + printf( "%s: Null buffer.\n", fn ); + return (fpga_desc * const)NULL; + } + if ( !bsize ) { + printf( "%s: Null buffer size.\n", fn ); + return (fpga_desc * const)NULL; + } + + return desc; +} + + +/* fpga_dev_info + * generic multiplexing code + */ +static int fpga_dev_info( int devnum ) +{ + int ret_val = FPGA_FAIL; /* assume failure */ + const fpga_desc * const desc = fpga_get_desc( devnum ); + + if ( desc ) { + PRINTF( "%s: Device Descriptor @ 0x%p\n", + __FUNCTION__, desc->devdesc ); + + switch ( desc->devtype ) { + case fpga_xilinx: +#if CONFIG_FPGA & CFG_FPGA_XILINX + printf( "Xilinx Device\nDescriptor @ 0x%p\n", desc ); + ret_val = xilinx_info( desc->devdesc ); +#else + fpga_no_sup( __FUNCTION__, "Xilinx devices" ); +#endif + break; + case fpga_altera: +#if CONFIG_FPGA & CFG_FPGA_ALTERA + printf( "Altera Device\nDescriptor @ 0x%p\n", desc ); + ret_val = altera_info( desc->devdesc ); +#else + fpga_no_sup( __FUNCTION__, "Altera devices" ); +#endif + break; + default: + printf( "%s: Invalid or unsupported device type %d\n", + __FUNCTION__, desc->devtype ); + } + } else { + printf( "%s: Invalid device number %d\n", + __FUNCTION__, devnum ); + } + + return ret_val; +} + + +/* fpga_reloc + * generic multiplexing code + */ +int fpga_reloc( fpga_type devtype, void *desc, ulong reloc_off ) +{ + int ret_val = FPGA_FAIL; + + PRINTF( "%s: Relocating Device of type %d @ 0x%p with offset %lx\n", + __FUNCTION__, devtype, desc, reloc_off ); + + switch ( devtype ) { + case fpga_xilinx: +#if CONFIG_FPGA & CFG_FPGA_XILINX + ret_val = xilinx_reloc( desc, reloc_off ); +#else + fpga_no_sup( __FUNCTION__, "Xilinx devices" ); +#endif + break; + case fpga_altera: +#if CONFIG_FPGA & CFG_FPGA_ALTERA + ret_val = altera_reloc( desc, reloc_off ); +#else + fpga_no_sup( __FUNCTION__, "Altera devices" ); +#endif + break; + default: + printf( "%s: Invalid or unsupported device type %d\n", + __FUNCTION__, devtype ); + } + + return ret_val; +} + +/* ------------------------------------------------------------------------- */ +/* fgpa_init is usually called from misc_init_r() and MUST be called + * before any of the other fpga functions are used. + */ +void fpga_init( ulong reloc_off ) +{ + relocation_offset = reloc_off; + next_desc = 0; + memset( desc_table, 0, sizeof(desc_table)); + + PRINTF( "%s: CONFIG_FPGA = 0x%x\n", __FUNCTION__, CONFIG_FPGA ); +#if 0 + PRINTF( "%s: CFG_FPGA_XILINX = 0x%x\n", __FUNCTION__, CFG_FPGA_XILINX ); + PRINTF( "%s: CFG_FPGA_ALTERA = 0x%x\n", __FUNCTION__, CFG_FPGA_ALTERA ); +#endif +} + +/* fpga_count + * Basic interface function to get the current number of devices available. + */ +const int fpga_count( void ) +{ + return next_desc; +} + +/* fpga_add + * Attempts to relocate the device/board specific interface code + * to the proper RAM locations and adds the device descriptor to + * the device table. + */ +int fpga_add( fpga_type devtype, void *desc ) +{ + int devnum = FPGA_INVALID_DEVICE; + + if ( next_desc < 0 ) { + printf( "%s: FPGA support not initialized!\n", __FUNCTION__ ); + } else if (( devtype > fpga_min_type ) && ( devtype < fpga_undefined )) { + if ( desc ) { + if ( next_desc < CONFIG_MAX_FPGA_DEVICES ) { + if ( fpga_reloc( devtype, desc, relocation_offset ) + == FPGA_SUCCESS ) { + devnum = next_desc; + desc_table[next_desc].devtype = devtype; + desc_table[next_desc++].devdesc = desc; + } else { + printf( "%s: Unable to relocate device interface table!\n", + __FUNCTION__ ); + } + } else { + printf( "%s: Exceeded Max FPGA device count\n", __FUNCTION__ ); + } + } else { + printf( "%s: NULL device descriptor\n", __FUNCTION__ ); + } + } else { + printf( "%s: Unsupported FPGA type %d\n", __FUNCTION__, devtype ); + } + + return devnum; +} + +/* + * Generic multiplexing code + */ +int fpga_load( int devnum, void *buf, size_t bsize ) +{ + int ret_val = FPGA_FAIL; /* assume failure */ + const fpga_desc * const desc = fpga_validate( devnum, buf, bsize, __FUNCTION__ ); + + if ( desc ) { + switch ( desc->devtype ) { + case fpga_xilinx: +#if CONFIG_FPGA & CFG_FPGA_XILINX + ret_val = xilinx_load( desc->devdesc, buf, bsize ); +#else + fpga_no_sup( __FUNCTION__, "Xilinx devices" ); +#endif + break; + case fpga_altera: +#if CONFIG_FPGA & CFG_FPGA_ALTERA + ret_val = altera_load( desc->devdesc, buf, bsize ); +#else + fpga_no_sup( __FUNCTION__, "Altera devices" ); +#endif + break; + default: + printf( "%s: Invalid or unsupported device type %d\n", + __FUNCTION__, desc->devtype ); + } + } + + return ret_val; +} + +/* fpga_dump + * generic multiplexing code + */ +int fpga_dump( int devnum, void *buf, size_t bsize ) +{ + int ret_val = FPGA_FAIL; /* assume failure */ + const fpga_desc * const desc = fpga_validate( devnum, buf, bsize, __FUNCTION__ ); + + if ( desc ) { + switch ( desc->devtype ) { + case fpga_xilinx: +#if CONFIG_FPGA & CFG_FPGA_XILINX + ret_val = xilinx_dump( desc->devdesc, buf, bsize ); +#else + fpga_no_sup( __FUNCTION__, "Xilinx devices" ); +#endif + break; + case fpga_altera: +#if CONFIG_FPGA & CFG_FPGA_ALTERA + ret_val = altera_dump( desc->devdesc, buf, bsize ); +#else + fpga_no_sup( __FUNCTION__, "Altera devices" ); +#endif + break; + default: + printf( "%s: Invalid or unsupported device type %d\n", + __FUNCTION__, desc->devtype ); + } + } + + return ret_val; +} + + +/* fpga_info + * front end to fpga_dev_info. If devnum is invalid, report on all + * available devices. + */ +int fpga_info( int devnum ) +{ + if ( devnum == FPGA_INVALID_DEVICE ) { + if ( next_desc > 0 ) { + int dev; + + for ( dev = 0; dev < next_desc; dev++ ) { + fpga_dev_info( dev ); + } + return FPGA_SUCCESS; + } else { + printf( "%s: No FPGA devices available.\n", __FUNCTION__ ); + return FPGA_FAIL; + } + } + else return fpga_dev_info( devnum ); +} + +/* ------------------------------------------------------------------------- */ + +#endif /* CONFIG_FPGA */ diff --git a/common/soft_i2c.c b/common/soft_i2c.c index 75aa49f..1c6da3c 100644 --- a/common/soft_i2c.c +++ b/common/soft_i2c.c @@ -298,7 +298,7 @@ int i2c_probe(uchar addr) int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) { int shift; - PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len%d\n", + PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n", chip, addr, alen, buffer, len); #ifdef CFG_I2C_EEPROM_ADDR_OVERFLOW @@ -362,6 +362,9 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len) int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) { int shift, failures = 0; + + PRINTD("i2c_write: chip %02X addr %02X alen %d buffer %p len %d\n", + chip, addr, alen, buffer, len); send_start(); if(write_byte(chip << 1)) { /* write cycle */ diff --git a/common/spartan2.c b/common/spartan2.c new file mode 100644 index 0000000..949c63c --- /dev/null +++ b/common/spartan2.c @@ -0,0 +1,470 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 /* core ppcboot definitions */ +#include /* Spartan-II device family */ + +#if (CONFIG_FPGA & (CFG_XILINX | CFG_SPARTAN2)) + +/* Define FPGA_DEBUG to get debug printf's */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#undef CFG_FPGA_CHECK_BUSY +#define CFG_FPGA_PROG_FEEDBACK + +/* Note: The assumption is that we cannot possibly run fast enough to + * overrun the device (the Slave Parallel mode can free run at 50MHz). + * If there is a need to operate slower, define CONFIG_FPGA_DELAY in + * the board config file to slow things down. + */ +#ifndef CONFIG_FPGA_DELAY +#define CONFIG_FPGA_DELAY() +#endif + +#ifndef CFG_FPGA_WAIT +#define CFG_FPGA_WAIT 10 +#endif + +static int Spartan2_sp_load( Xilinx_desc *desc, void *buf, size_t bsize ); +static int Spartan2_sp_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +/* static int Spartan2_sp_info( Xilinx_desc *desc ); */ +static int Spartan2_sp_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +static int Spartan2_ss_load( Xilinx_desc *desc, void *buf, size_t bsize ); +static int Spartan2_ss_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +/* static int Spartan2_ss_info( Xilinx_desc *desc ); */ +static int Spartan2_ss_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +/* ------------------------------------------------------------------------- */ +/* Spartan-II Generic Implementation */ +int Spartan2_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); + ret_val = Spartan2_ss_load (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); + ret_val = Spartan2_sp_load (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int Spartan2_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); + ret_val = Spartan2_ss_dump (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); + ret_val = Spartan2_sp_dump (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + +int Spartan2_info( Xilinx_desc *desc ) +{ + return FPGA_SUCCESS; +} + + +int Spartan2_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (desc->family != Xilinx_Spartan2) { + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + return FPGA_FAIL; + } else + switch (desc->iface) { + case slave_serial: + ret_val = Spartan2_ss_reloc (desc, reloc_offset); + break; + + case slave_parallel: + ret_val = Spartan2_sp_reloc (desc, reloc_offset); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + + return ret_val; +} + + +/* ------------------------------------------------------------------------- */ +/* Spartan-II Slave Parallel Generic Implementation */ + +static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns; + + PRINTF ("%s: start with interface functions @ 0x%p\n", + __FUNCTION__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; /* make a local copy */ + unsigned long ts; /* timestamp */ + + PRINTF ("%s: Function Table:\n" + "ptr:\t0x%p\n" + "struct: 0x%p\n" + "pre: 0x%p\n" + "pgm:\t0x%p\n" + "init:\t0x%p\n" + "err:\t0x%p\n" + "clk:\t0x%p\n" + "cs:\t0x%p\n" + "wr:\t0x%p\n" + "read data:\t0x%p\n" + "write data:\t0x%p\n" + "busy:\t0x%p\n" + "abort:\t0x%p\n", + "post:\t0x%p\n\n", + __FUNCTION__, &fn, fn, fn->pre, fn->pgm, fn->init, fn->err, + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, fn->busy, + fn->abort, fn->post); + + /* + * This code is designed to emulate the "Express Style" + * Continuous Data Loading in Slave Parallel Mode for + * the Spartan-II Family. + */ +#ifdef CFG_FPGA_PROG_FEEDBACK + printf ("Loading FPGA Device %d...\n", cookie); +#endif + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* Establish the initial state */ + (*fn->pgm) (TRUE, TRUE, cookie); /* Assert the program, commit */ + + /* Get ready for the burn */ + CONFIG_FPGA_DELAY (); + (*fn->pgm) (FALSE, TRUE, cookie); /* Deassert the program, commit */ + + ts = get_timer (0); /* get current time */ + /* Now wait for INIT and BUSY to go high */ + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for INIT to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + return FPGA_FAIL; + } + } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); + + (*fn->wr) (TRUE, TRUE, cookie); /* Assert write, commit */ + (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + /* Load the data */ + while (bytecount < bsize) { + /* XXX - do we check for an Ctrl-C press in here ??? */ + /* XXX - Check the error bit? */ + + (*fn->wdata) (data[bytecount++], TRUE, cookie); /* write the data */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + +#ifdef CFG_FPGA_CHECK_BUSY + ts = get_timer (0); /* get current time */ + while ((*fn->busy) (cookie)) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for BUSY to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + return FPGA_FAIL; + } + } +#endif + +#ifdef CFG_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + CONFIG_FPGA_DELAY (); + (*fn->cs) (FALSE, TRUE, cookie); /* Deassert the chip select */ + (*fn->wr) (FALSE, TRUE, cookie); /* Deassert the write pin */ + +#ifdef CFG_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + + /* now check for done signal */ + ts = get_timer (0); /* get current time */ + ret_val = FPGA_SUCCESS; + while ((*fn->done) (cookie) == FPGA_FAIL) { + /* XXX - we should have a check in here somewhere to + * make sure we aren't busy forever... */ + + CONFIG_FPGA_DELAY (); + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + if (get_timer (ts) > CFG_FPGA_WAIT) { /* check the time */ + puts ("** Timeout waiting for DONE to clear.\n"); + (*fn->abort) (cookie); /* abort the burn */ + ret_val = FPGA_FAIL; + break; + } + } + + if (ret_val == FPGA_SUCCESS) { +#ifdef CFG_FPGA_PROG_FEEDBACK + puts ("Done.\n"); +#endif + } + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + + else { +#ifdef CFG_FPGA_PROG_FEEDBACK + puts ("Fail.\n"); +#endif + } + + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + +static int Spartan2_sp_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Parallel_fns *fn = desc->iface_fns; + + if (fn) { + unsigned char *data = (unsigned char *) buf; + size_t bytecount = 0; + int cookie = desc->cookie; /* make a local copy */ + + printf ("Starting Dump of FPGA Device %d...\n", cookie); + + (*fn->cs) (TRUE, TRUE, cookie); /* Assert chip select, commit */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + + /* dump the data */ + while (bytecount < bsize) { + /* XXX - do we check for an Ctrl-C press in here ??? */ + + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + (*fn->rdata) (&(data[bytecount++]), cookie); /* read the data */ +#ifdef CFG_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); /* let them know we are alive */ +#endif + } + + (*fn->cs) (FALSE, FALSE, cookie); /* Deassert the chip select */ + (*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */ + (*fn->clk) (TRUE, TRUE, cookie); /* Assert the clock pin */ + +#ifdef CFG_FPGA_PROG_FEEDBACK + putc ('\n'); /* terminate the dotted line */ +#endif + puts ("Done.\n"); + + /* XXX - checksum the data? */ + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; +} + + +static int Spartan2_sp_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Parallel_fns *fn_r, *fn = + (Xilinx_Spartan2_Slave_Parallel_fns *) (desc->iface_fns); + + if (fn) { + ulong addr; + + /* Get the relocated table address */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Spartan2_Slave_Parallel_fns *) addr; + + if (!fn_r->relocated) { + + if (memcmp (fn_r, fn, + sizeof (Xilinx_Spartan2_Slave_Parallel_fns)) + == 0) { + /* good copy of the table, fix the descriptor pointer */ + desc->iface_fns = fn_r; + } else { + PRINTF ("%s: Invalid function table at 0x%p\n", + __FUNCTION__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s: Relocating descriptor at 0x%p\n", __FUNCTION__, + desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + + addr = (ulong) (fn->err) + reloc_offset; + fn_r->err = (Xilinx_err_fn) addr; + + addr = (ulong) (fn->cs) + reloc_offset; + fn_r->cs = (Xilinx_cs_fn) addr; + + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + + addr = (ulong) (fn->rdata) + reloc_offset; + fn_r->rdata = (Xilinx_rdata_fn) addr; + + addr = (ulong) (fn->wdata) + reloc_offset; + fn_r->wdata = (Xilinx_wdata_fn) addr; + + addr = (ulong) (fn->busy) + reloc_offset; + fn_r->busy = (Xilinx_busy_fn) addr; + + addr = (ulong) (fn->abort) + reloc_offset; + fn_r->abort = (Xilinx_abort_fn) addr; + + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + + fn_r->relocated = TRUE; + + } else { + /* this table has already been moved */ + /* XXX - should check to see if the descriptor is correct */ + desc->iface_fns = fn_r; + } + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} + +/* ------------------------------------------------------------------------- */ + +static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + printf ("%s: Slave Serial Loading is still unsupported\n", + __FUNCTION__); + return FPGA_FAIL; +} + +static int Spartan2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + printf ("%s: Slave Serial Dumping is still unsupported\n", + __FUNCTION__); + return FPGA_FAIL; +} + +static int Spartan2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume the worst */ + Xilinx_Spartan2_Slave_Serial_fns *fn = + (Xilinx_Spartan2_Slave_Serial_fns *) (desc->iface_fns); + + if (fn) { + printf ("%s: Slave Serial Loading is still unsupported\n", + __FUNCTION__); + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + + return ret_val; + +} + +#endif diff --git a/common/virtex2.c b/common/virtex2.c new file mode 100644 index 0000000..b519be9 --- /dev/null +++ b/common/virtex2.c @@ -0,0 +1,543 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * Keith Outwater, keith_outwater@mvis.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 + * + */ + +/* + * Configuration support for Xilinx Virtex2 devices. Based + * on spartan2.c (Rich Ireland, rireland@enterasys.com). + */ + +#include +#include + +#if (CONFIG_FPGA & (CFG_XILINX | CFG_VIRTEX2)) + +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* + * If the SelectMap interface can be overrun by the processor, define + * CFG_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration + * file and add board-specific support for checking BUSY status. By default, + * assume that the SelectMap interface cannot be overrun. + */ +#ifndef CFG_FPGA_CHECK_BUSY +#undef CFG_FPGA_CHECK_BUSY +#endif + +#ifndef CONFIG_FPGA_DELAY +#define CONFIG_FPGA_DELAY() +#endif + +#ifndef CFG_FPGA_PROG_FEEDBACK +#define CFG_FPGA_PROG_FEEDBACK +#endif + +/* + * Don't allow config cycle to be interrupted + */ +#ifndef CFG_FPGA_CHECK_CTRLC +#undef CFG_FPGA_CHECK_CTRLC +#endif + +/* + * Check for errors during configuration by default + */ +#ifndef CFG_FPGA_CHECK_ERROR +#define CFG_FPGA_CHECK_ERROR +#endif + +/* + * The default timeout in mS for INIT_B to deassert after PROG_B has + * been deasserted. Per the latest Virtex II Handbook (page 347), the + * max time from PORG_B deassertion to INIT_B deassertion is 4uS per + * data frame for the XC2V8000. The XC2V8000 has 2860 data frames + * which yields 11.44 mS. So let's make it bigger in order to handle + * an XC2V1000, if anyone can ever get ahold of one. + */ +#ifndef CFG_FPGA_WAIT_INIT +#define CFG_FPGA_WAIT_INIT 500 /* time in milliseconds */ +#endif + +/* + * The default timeout for waiting for BUSY to deassert during configuration. + * This is normally not necessary since for most reasonable configuration + * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary. + */ +#ifndef CFG_FPGA_WAIT_BUSY +#define CFG_FPGA_WAIT_BUSY 5 /* time in milliseconds */ +#endif + +/* Default timeout for waiting for FPGA to enter operational mode after + * configuration data has been written. + */ +#ifndef CFG_FPGA_WAIT_CONFIG +#define CFG_FPGA_WAIT_CONFIG 200 /* time in milliseconds */ +#endif + +static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize); +static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize); +static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset); + +static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize); +static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize); +static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset); + +int Virtex2_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); + ret_val = Virtex2_ss_load (desc, buf, bsize); + break; + + case slave_selectmap: + PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); + ret_val = Virtex2_ssm_load (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + return ret_val; +} + +int Virtex2_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + + switch (desc->iface) { + case slave_serial: + PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); + ret_val = Virtex2_ss_dump (desc, buf, bsize); + break; + + case slave_parallel: + PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); + ret_val = Virtex2_ssm_dump (desc, buf, bsize); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + return ret_val; +} + +int Virtex2_info (Xilinx_desc * desc) +{ + return FPGA_SUCCESS; +} + +int Virtex2_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; + + if (desc->family != Xilinx_Virtex2) { + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + return FPGA_FAIL; + } else + switch (desc->iface) { + case slave_serial: + ret_val = Virtex2_ss_reloc (desc, reloc_offset); + break; + + case slave_selectmap: + ret_val = Virtex2_ssm_reloc (desc, reloc_offset); + break; + + default: + printf ("%s: Unsupported interface type, %d\n", + __FUNCTION__, desc->iface); + } + return ret_val; +} + +/* + * Virtex-II Slave SelectMap configuration loader. Configuration via + * SelectMap is as follows: + * 1. Set the FPGA's PROG_B line low. + * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. + * 3. Write data to the SelectMap port. If INIT_B goes low at any time + * this process, a configuration error (most likely CRC failure) has + * ocurred. At this point a status word may be read from the + * SelectMap interface to determine the source of the problem (You + * could, for instance, put this in you 'abort' function handler). + * 4. After all data has been written, test the state of the FPGA + * INIT_B and DONE lines. If both are high, configuration has + * succeeded. Congratulations! + */ +static int Virtex2_ssm_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; + + PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", + __FUNCTION__, __LINE__, fn); + + if (fn) { + size_t bytecount = 0; + unsigned char *data = (unsigned char *) buf; + int cookie = desc->cookie; + unsigned long ts; + + /* Gotta split this one up (so the stack won't blow??) */ + PRINTF ("%s:%d: Function Table:\n" + " base 0x%p\n" + " struct 0x%p\n" + " pre 0x%p\n" + " prog 0x%p\n" + " init 0x%p\n" + " error 0x%p\n", + __FUNCTION__, __LINE__, + &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); + PRINTF (" clock 0x%p\n" + " cs 0x%p\n" + " write 0x%p\n" + " rdata 0x%p\n" + " wdata 0x%p\n" + " busy 0x%p\n" + " abort 0x%p\n" + " post 0x%p\n\n", + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, + fn->busy, fn->abort, fn->post); + +#ifdef CFG_FPGA_PROG_FEEDBACK + printf ("Initializing FPGA Device %d...\n", cookie); +#endif + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) { + (*fn->pre) (cookie); + } + + /* + * Assert the program line. The minimum pulse width for + * Virtex II devices is 300 nS (Tprogram parameter in datasheet). + * There is no maximum value for the pulse width. Check to make + * sure that INIT_B goes low after assertion of PROG_B + */ + (*fn->pgm) (TRUE, TRUE, cookie); + udelay (10); + ts = get_timer (0); + do { + if (get_timer (ts) > CFG_FPGA_WAIT_INIT) { + printf ("%s:%d: ** Timeout after %d mS waiting for INIT" + " to assert.\n", __FUNCTION__, __LINE__, + CFG_FPGA_WAIT_INIT); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + } while (!(*fn->init) (cookie)); + + (*fn->pgm) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); + + /* + * Start a timer and wait for INIT_B to go high + */ + ts = get_timer (0); + do { + CONFIG_FPGA_DELAY (); + if (get_timer (ts) > CFG_FPGA_WAIT_INIT) { + printf ("%s:%d: ** Timeout after %d mS waiting for INIT" + " to deassert.\n", __FUNCTION__, __LINE__, + CFG_FPGA_WAIT_INIT); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); + + (*fn->wr) (TRUE, TRUE, cookie); + (*fn->cs) (TRUE, TRUE, cookie); + + udelay (10000); + + /* + * Load the data byte by byte + */ + while (bytecount < bsize) { +#ifdef CFG_FPGA_CHECK_CTRLC + if (ctrlc ()) { + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#endif +#ifdef CFG_FPGA_CHECK_ERROR + if ((*fn->init) (cookie)) { + printf ("%s:%d: ** Error: INIT asserted during" + " configuration\n", __FUNCTION__, __LINE__); + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#endif + (*fn->wdata) (data[bytecount++], TRUE, cookie); + CONFIG_FPGA_DELAY (); + + /* + * Cycle the clock pin + */ + (*fn->clk) (FALSE, TRUE, cookie); + CONFIG_FPGA_DELAY (); + (*fn->clk) (TRUE, TRUE, cookie); + +#ifdef CFG_FPGA_CHECK_BUSY + ts = get_timer (0); + while ((*fn->busy) (cookie)) { + if (get_timer (ts) > CFG_FPGA_WAIT_BUSY) { + printf ("%s:%d: ** Timeout after %d mS waiting for" + " BUSY to deassert\n", + __FUNCTION__, __LINE__, CFG_FPGA_WAIT_BUSY); + (*fn->abort) (cookie); + return FPGA_FAIL; + } + } +#endif + +#ifdef CFG_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); +#endif + } + + /* + * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. + */ + CONFIG_FPGA_DELAY (); + (*fn->cs) (FALSE, TRUE, cookie); + (*fn->wr) (FALSE, TRUE, cookie); + +#ifdef CFG_FPGA_PROG_FEEDBACK + putc ('\n'); +#endif + + /* + * Check for successful configuration. FPGA INIT_B and DONE should + * both be high upon successful configuration. + */ + ts = get_timer (0); + ret_val = FPGA_SUCCESS; + while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { + if (get_timer (ts) > CFG_FPGA_WAIT_CONFIG) { + printf ("%s:%d: ** Timeout after %d mS waiting for DONE to" + "assert and INIT to deassert\n", + __FUNCTION__, __LINE__, CFG_FPGA_WAIT_CONFIG); + (*fn->abort) (cookie); + ret_val = FPGA_FAIL; + break; + } + } + + if (ret_val == FPGA_SUCCESS) { +#ifdef CFG_FPGA_PROG_FEEDBACK + printf ("Initialization of FPGA device %d complete\n", cookie); +#endif + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) { + (*fn->post) (cookie); + } + } else { +#ifdef CFG_FPGA_PROG_FEEDBACK + printf ("** Initialization of FPGA device %d FAILED\n", + cookie); +#endif + } + } else { + printf ("%s:%d: NULL Interface function table!\n", + __FUNCTION__, __LINE__); + } + return ret_val; +} + +/* + * Read the FPGA configuration data + */ +static int Virtex2_ssm_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + Xilinx_Virtex2_Slave_SelectMap_fns *fn = desc->iface_fns; + + if (fn) { + unsigned char *data = (unsigned char *) buf; + size_t bytecount = 0; + int cookie = desc->cookie; + + printf ("Starting Dump of FPGA Device %d...\n", cookie); + + (*fn->cs) (TRUE, TRUE, cookie); + (*fn->clk) (TRUE, TRUE, cookie); + + while (bytecount < bsize) { +#ifdef CFG_FPGA_CHECK_CTRLC + if (ctrlc ()) { + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#endif + /* + * Cycle the clock and read the data + */ + (*fn->clk) (FALSE, TRUE, cookie); + (*fn->clk) (TRUE, TRUE, cookie); + (*fn->rdata) (&(data[bytecount++]), cookie); +#ifdef CFG_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc ('.'); +#endif + } + + /* + * Deassert CS_B and cycle the clock to deselect the device. + */ + (*fn->cs) (FALSE, FALSE, cookie); + (*fn->clk) (FALSE, TRUE, cookie); + (*fn->clk) (TRUE, TRUE, cookie); + +#ifdef CFG_FPGA_PROG_FEEDBACK + putc ('\n'); +#endif + puts ("Done.\n"); + } else { + printf ("%s:%d: NULL Interface function table!\n", + __FUNCTION__, __LINE__); + } + return ret_val; +} + +/* + * Relocate the addresses in the function table from FLASH (or ROM, + * or whatever) to RAM. + */ +static int Virtex2_ssm_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + ulong addr; + int ret_val = FPGA_FAIL; + Xilinx_Virtex2_Slave_SelectMap_fns *fn_r, *fn = + (Xilinx_Virtex2_Slave_SelectMap_fns *) (desc->iface_fns); + + if (fn) { + /* + * Get the relocated table address + */ + addr = (ulong) fn + reloc_offset; + fn_r = (Xilinx_Virtex2_Slave_SelectMap_fns *) addr; + + /* + * Check to see if the table has already been relocated. If not, do + * a sanity check to make sure there is a faithful copy of the + * FLASH based function table in RAM, then adjust the table. + */ + if (!fn_r->relocated) { + if (memcmp + (fn_r, fn, sizeof (Xilinx_Virtex2_Slave_SelectMap_fns)) + == 0) { + desc->iface_fns = fn_r; + } else { + PRINTF ("%s:%d: Invalid function table at 0x%p\n", + __FUNCTION__, __LINE__, fn_r); + return FPGA_FAIL; + } + + PRINTF ("%s:%d: Relocating descriptor at 0x%p\n", + __FUNCTION__, __LINE__, desc); + + addr = (ulong) (fn->pre) + reloc_offset; + fn_r->pre = (Xilinx_pre_fn) addr; + addr = (ulong) (fn->pgm) + reloc_offset; + fn_r->pgm = (Xilinx_pgm_fn) addr; + addr = (ulong) (fn->init) + reloc_offset; + fn_r->init = (Xilinx_init_fn) addr; + addr = (ulong) (fn->done) + reloc_offset; + fn_r->done = (Xilinx_done_fn) addr; + addr = (ulong) (fn->err) + reloc_offset; + fn_r->err = (Xilinx_err_fn) addr; + addr = (ulong) (fn->clk) + reloc_offset; + fn_r->clk = (Xilinx_clk_fn) addr; + addr = (ulong) (fn->cs) + reloc_offset; + fn_r->cs = (Xilinx_cs_fn) addr; + addr = (ulong) (fn->wr) + reloc_offset; + fn_r->wr = (Xilinx_wr_fn) addr; + addr = (ulong) (fn->rdata) + reloc_offset; + fn_r->rdata = (Xilinx_rdata_fn) addr; + addr = (ulong) (fn->wdata) + reloc_offset; + fn_r->wdata = (Xilinx_wdata_fn) addr; + addr = (ulong) (fn->busy) + reloc_offset; + fn_r->busy = (Xilinx_busy_fn) addr; + addr = (ulong) (fn->abort) + reloc_offset; + fn_r->abort = (Xilinx_abort_fn) addr; + addr = (ulong) (fn->post) + reloc_offset; + fn_r->post = (Xilinx_post_fn) addr; + fn_r->relocated = TRUE; + } else { + printf ("%s:%d: Function table @0x%p has already been relocated\n", __FUNCTION__, __LINE__, fn_r); + desc->iface_fns = fn_r; + } + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: NULL Interface function table!\n", __FUNCTION__); + } + return ret_val; +} + +static int Virtex2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__); + return FPGA_FAIL; +} + +static int Virtex2_ss_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__); + return FPGA_FAIL; +} + +static int Virtex2_ss_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; + Xilinx_Virtex2_Slave_Serial_fns *fn = + (Xilinx_Virtex2_Slave_Serial_fns *) (desc->iface_fns); + + if (fn) { + printf ("%s:%d: Slave Serial Loading is unsupported\n", + __FUNCTION__, __LINE__); + } else { + printf ("%s:%d: NULL Interface function table!\n", + __FUNCTION__, __LINE__); + } + return ret_val; +} +#endif + +/* vim: set ts=4 tw=78: */ diff --git a/common/xilinx.c b/common/xilinx.c new file mode 100644 index 0000000..cb153e1 --- /dev/null +++ b/common/xilinx.c @@ -0,0 +1,269 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * Keith Outwater, keith_outwater@mvis.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 + * + */ + +/* + * Xilinx FPGA support + */ + +#include +#include +#include + +#if (CONFIG_FPGA & CFG_FPGA_XILINX) + +#if 0 +#define FPGA_DEBUG +#endif + +/* Define FPGA_DEBUG to get debug printf's */ +#ifdef FPGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* Local Static Functions */ +static int xilinx_validate (Xilinx_desc * desc, char *fn); + +/* ------------------------------------------------------------------------- */ + +int xilinx_load (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!xilinx_validate (desc, __FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else + switch (desc->family) { + case Xilinx_Spartan2: +#if (CONFIG_FPGA & CFG_SPARTAN2) + PRINTF ("%s: Launching the Spartan-II Loader...\n", + __FUNCTION__); + ret_val = Spartan2_load (desc, buf, bsize); +#else + printf ("%s: No support for Spartan-II devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Virtex2: +#if (CONFIG_FPGA & CFG_VIRTEX2) + PRINTF ("%s: Launching the Virtex-II Loader...\n", + __FUNCTION__); + ret_val = Virtex2_load (desc, buf, bsize); +#else + printf ("%s: No support for Virtex-II devices.\n", + __FUNCTION__); +#endif + break; + + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + + return ret_val; +} + +int xilinx_dump (Xilinx_desc * desc, void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!xilinx_validate (desc, __FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else + switch (desc->family) { + case Xilinx_Spartan2: +#if (CONFIG_FPGA & CFG_SPARTAN2) + PRINTF ("%s: Launching the Spartan-II Reader...\n", + __FUNCTION__); + ret_val = Spartan2_dump (desc, buf, bsize); +#else + printf ("%s: No support for Spartan-II devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Virtex2: +#if (CONFIG_FPGA & CFG_VIRTEX2) + PRINTF ("%s: Launching the Virtex-II Reader...\n", + __FUNCTION__); + ret_val = Virtex2_dump (desc, buf, bsize); +#else + printf ("%s: No support for Virtex-II devices.\n", + __FUNCTION__); +#endif + break; + + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + + return ret_val; +} + +int xilinx_info (Xilinx_desc * desc) +{ + int ret_val = FPGA_FAIL; + + if (xilinx_validate (desc, __FUNCTION__)) { + printf ("Family: \t"); + switch (desc->family) { + case Xilinx_Spartan2: + printf ("Spartan-II\n"); + break; + case Xilinx_Virtex2: + printf ("Virtex-II\n"); + break; + /* Add new family types here */ + default: + printf ("Unknown family type, %d\n", desc->family); + } + + printf ("Interface type:\t"); + switch (desc->iface) { + case slave_serial: + printf ("Slave Serial\n"); + break; + case master_serial: /* Not used */ + printf ("Master Serial\n"); + break; + case slave_parallel: + printf ("Slave Parallel\n"); + break; + case jtag_mode: /* Not used */ + printf ("JTAG Mode\n"); + break; + case slave_selectmap: + printf ("Slave SelectMap Mode\n"); + break; + case master_selectmap: + printf ("Master SelectMap Mode\n"); + break; + /* Add new interface types here */ + default: + printf ("Unsupported interface type, %d\n", desc->iface); + } + + printf ("Device Size: \t%d bytes\n" + "Cookie: \t0x%x (%d)\n", + desc->size, desc->cookie, desc->cookie); + + if (desc->iface_fns) { + printf ("Device Function Table @ 0x%p\n", desc->iface_fns); + switch (desc->family) { + case Xilinx_Spartan2: +#if (CONFIG_FPGA & CFG_SPARTAN2) + Spartan2_info (desc); +#else + /* just in case */ + printf ("%s: No support for Spartan-II devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Virtex2: +#if (CONFIG_FPGA & CFG_VIRTEX2) + Virtex2_info (desc); +#else + /* just in case */ + printf ("%s: No support for Virtex-II devices.\n", + __FUNCTION__); +#endif + break; + /* Add new family types here */ + default: + /* we don't need a message here - we give one up above */ + } + } else + printf ("No Device Function Table.\n"); + + ret_val = FPGA_SUCCESS; + } else { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } + + return ret_val; +} + +int xilinx_reloc (Xilinx_desc * desc, ulong reloc_offset) +{ + int ret_val = FPGA_FAIL; /* assume a failure */ + + if (!xilinx_validate (desc, __FUNCTION__)) { + printf ("%s: Invalid device descriptor\n", __FUNCTION__); + } else + switch (desc->family) { + case Xilinx_Spartan2: +#if (CONFIG_FPGA & CFG_SPARTAN2) + ret_val = Spartan2_reloc (desc, reloc_offset); +#else + printf ("%s: No support for Spartan-II devices.\n", + __FUNCTION__); +#endif + break; + case Xilinx_Virtex2: +#if (CONFIG_FPGA & CFG_VIRTEX2) + ret_val = Virtex2_reloc (desc, reloc_offset); +#else + printf ("%s: No support for Virtex-II devices.\n", + __FUNCTION__); +#endif + break; + /* Add new family types here */ + default: + printf ("%s: Unsupported family type, %d\n", + __FUNCTION__, desc->family); + } + + return ret_val; +} + + +/* ------------------------------------------------------------------------- */ + +static int xilinx_validate (Xilinx_desc * desc, char *fn) +{ + int ret_val = FALSE; + + if (desc) { + if ((desc->family > min_xilinx_type) && + (desc->family < max_xilinx_type)) { + if ((desc->iface > min_xilinx_iface_type) && + (desc->iface < max_xilinx_iface_type)) { + if (desc->size) { + ret_val = TRUE; + } else + printf ("%s: NULL part size\n", fn); + } else + printf ("%s: Invalid Interface type, %d\n", + fn, desc->iface); + } else + printf ("%s: Invalid family type, %d\n", fn, desc->family); + } else + printf ("%s: NULL descriptor!\n", fn); + + return ret_val; +} + +#endif /* CONFIG_FPGA & CFG_FPGA_XILINX */ diff --git a/cpu/arm720t/cpu.c b/cpu/arm720t/cpu.c index c69cfd8..d857834 100644 --- a/cpu/arm720t/cpu.c +++ b/cpu/arm720t/cpu.c @@ -37,36 +37,36 @@ /* read co-processor 15, register #1 (control register) */ static unsigned long read_p15_c1(void) { - unsigned long value; - - __asm__ __volatile__( - "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" - : "=r" (value) - : - : "memory"); - //printf("p15/c1 is = %08lx\n", value); - return value; + unsigned long value; + + __asm__ __volatile__( + "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" + : "=r" (value) + : + : "memory"); + /* printf("p15/c1 is = %08lx\n", value); */ + return value; } /* write to co-processor 15, register #1 (control register) */ static void write_p15_c1(unsigned long value) { - //printf("write %08lx to p15/c1\n", value); - __asm__ __volatile__( - "mcr p15, 0, %0, c1, c0, 0 @ write it back\n" - : - : "r" (value) - : "memory"); - - read_p15_c1(); + /* printf("write %08lx to p15/c1\n", value); */ + __asm__ __volatile__( + "mcr p15, 0, %0, c1, c0, 0 @ write it back\n" + : + : "r" (value) + : "memory"); + + read_p15_c1(); } -static void cp_delay(void) +static void cp_delay (void) { - volatile int i; + volatile int i; - /* copro seems to need some delay between reading and writing */ - for (i=0; i<100; i++); + /* copro seems to need some delay between reading and writing */ + for (i = 0; i < 100; i++); } /* See also ARM Ref. Man. */ @@ -79,96 +79,102 @@ static void cp_delay(void) #define C1_ROM_PROT (1<<9) /* ROM protection */ #define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ -void cpu_init(bd_t *bd) +int cpu_init (gd_t * gd) { - /* - * setup up stack if necessary - */ + /* + * setup up stack if necessary + */ #ifdef CONFIG_USE_IRQ - IRQ_STACK_START = _armboot_end + - CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4; - FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ; - _armboot_real_end = FIQ_STACK_START + 4; + IRQ_STACK_START = _armboot_end + \ + CONFIG_STACKSIZE + \ + CONFIG_STACKSIZE_IRQ - 4; + FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ; + _armboot_real_end = FIQ_STACK_START + 4; #else - _armboot_real_end = _armboot_end + CONFIG_STACKSIZE; + _armboot_real_end = _armboot_end + CONFIG_STACKSIZE; #endif + return (0); } -void cleanup_before_linux(bd_t *bd) +int cleanup_before_linux (gd_t *dummy) { - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - * and we set the CPU-speed to 73 MHz - see start.S for details - */ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + * and we set the CPU-speed to 73 MHz - see start.S for details + */ - unsigned long i; + unsigned long i; - disable_interrupts(); + disable_interrupts (); - /* turn off I-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); - i &= ~0x1000; - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); + /* turn off I-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~0x1000; + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - /* flush I-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i)); + /* flush I-cache */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); #ifdef CONFIG_ARM7_REVD - /* go to high speed */ - IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73; + /* go to high speed */ + IO_SYSCON3 = (IO_SYSCON3 & ~CLKCTL) | CLKCTL_73; #endif + return 0; } -void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_reset (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]) { - extern void reset_cpu(ulong addr); + extern void reset_cpu (ulong addr); - disable_interrupts(); - reset_cpu(0); - /*NOTREACHED*/ -} + disable_interrupts (); + reset_cpu (0); + /*NOTREACHED*/} -void icache_enable(void) +void icache_enable (void) { - ulong reg; - reg = read_p15_c1(); - cp_delay(); - write_p15_c1(reg | C1_IDC); + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_IDC); } -void icache_disable(void) +void icache_disable (void) { - ulong reg; - reg = read_p15_c1(); - cp_delay(); - write_p15_c1(reg & ~C1_IDC); + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_IDC); } -int icache_status(void) +int icache_status (void) { - return (read_p15_c1() & C1_IDC) != 0; + return (read_p15_c1 () & C1_IDC) != 0; } -void dcache_enable(void) +void dcache_enable (void) { - ulong reg; - reg = read_p15_c1(); - cp_delay(); - write_p15_c1(reg | C1_IDC); + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_IDC); } -void dcache_disable(void) +void dcache_disable (void) { - ulong reg; - reg = read_p15_c1(); - cp_delay(); - write_p15_c1(reg & ~C1_IDC); + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_IDC); } -int dcache_status(void) +int dcache_status (void) { - return (read_p15_c1() & C1_IDC) != 0; + return (read_p15_c1 () & C1_IDC) != 0; } diff --git a/cpu/arm920t/cpu.c b/cpu/arm920t/cpu.c index b2f5d69..d9944eb 100644 --- a/cpu/arm920t/cpu.c +++ b/cpu/arm920t/cpu.c @@ -36,148 +36,154 @@ /* it makes no sense to use the caches if the MMU also isn't used */ #ifdef USE_920T_MMU /* read co-processor 15, register #1 (control register) */ -static unsigned long read_p15_c1(void) +static unsigned long read_p15_c1 (void) { - unsigned long value; + unsigned long value; + + __asm__ __volatile__( + "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" + : "=r" (value) + : + : "memory"); - __asm__ __volatile__( - "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n" - : "=r" (value) - : - : "memory"); #ifdef MMU_DEBUG - printf("p15/c1 is = %08lx\n", value); + printf ("p15/c1 is = %08lx\n", value); #endif - return value; + return value; } /* write to co-processor 15, register #1 (control register) */ -static void write_p15_c1(unsigned long value) +static void write_p15_c1 (unsigned long value) { #ifdef MMU_DEBUG - printf("write %08lx to p15/c1\n", value); + printf ("write %08lx to p15/c1\n", value); #endif - __asm__ __volatile__( - "mcr p15, 0, %0, c1, c0, 0 @ write it back\n" - : - : "r" (value) - : "memory"); - read_p15_c1(); + __asm__ __volatile__( + "mcr p15, 0, %0, c1, c0, 0 @ write it back\n" + : + : "r" (value) + : "memory"); + + read_p15_c1 (); } -static void cp_delay(void) +static void cp_delay (void) { - volatile int i; + volatile int i; - /* copro seems to need some delay between reading and writing */ - for (i=0; i<100; i++); + /* copro seems to need some delay between reading and writing */ + for (i = 0; i < 100; i++); } /* See also ARM Ref. Man. */ -#define C1_MMU (1<<0) /* mmu off/on */ -#define C1_ALIGN (1<<1) /* alignment faults off/on */ -#define C1_DC (1<<2) /* dcache off/on */ +#define C1_MMU (1<<0) /* mmu off/on */ +#define C1_ALIGN (1<<1) /* alignment faults off/on */ +#define C1_DC (1<<2) /* dcache off/on */ #define C1_BIG_ENDIAN (1<<7) /* big endian off/on */ -#define C1_SYS_PROT (1<<8) /* system protection */ -#define C1_ROM_PROT (1<<9) /* ROM protection */ -#define C1_IC (1<<12) /* icache off/on */ +#define C1_SYS_PROT (1<<8) /* system protection */ +#define C1_ROM_PROT (1<<9) /* ROM protection */ +#define C1_IC (1<<12) /* icache off/on */ #define C1_HIGH_VECTORS (1<<13) /* location of vectors: low/high addresses */ -#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */ -#endif +#define RESERVED_1 (0xf << 3) /* must be 111b for R/W */ +#endif /* USE_920T_MMU */ -void cpu_init(bd_t *bd) +int cpu_init (gd_t *gd) { - /* - * setup up stack if necessary - */ + /* + * setup up stack if necessary + */ #ifdef CONFIG_USE_IRQ - IRQ_STACK_START = _armboot_end + - CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4; - FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ; - _armboot_real_end = FIQ_STACK_START + 4; + IRQ_STACK_START = _armboot_end + + CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4; + FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ; + _armboot_real_end = FIQ_STACK_START + 4; #else - _armboot_real_end = _armboot_end + CONFIG_STACKSIZE; + _armboot_real_end = _armboot_end + CONFIG_STACKSIZE; #endif + return (0); } -void cleanup_before_linux(bd_t *bd) +int cleanup_before_linux (gd_t *dummy) { - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * we turn off caches etc ... - */ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * we turn off caches etc ... + */ #ifdef USE_920T_MMU - unsigned long i; + unsigned long i; #endif - disable_interrupts(); + disable_interrupts (); #ifdef USE_920T_MMU - /* turn off I/D-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); - i &= ~(C1_DC|C1_IC); - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); - - /* flush I/D-cache */ - i = 0; - asm ("mcr p15, 0, %0, c7, c7, 0": : "r" (i)); + /* turn off I/D-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~(C1_DC | C1_IC); + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + + /* flush I/D-cache */ + i = 0; + asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i)); #endif - + return (0); } -void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_reset (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]) { - extern void reset_cpu(ulong addr); + extern void reset_cpu (ulong addr); - disable_interrupts(); - reset_cpu(0); - /*NOTREACHED*/ -} + disable_interrupts (); + reset_cpu (0); + /*NOTREACHED*/} #ifdef USE_920T_MMU -void icache_enable(void) +void icache_enable (void) { - ulong reg; - reg = read_p15_c1(); - cp_delay(); - write_p15_c1(reg | C1_IC); + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_IC); } -void icache_disable(void) +void icache_disable (void) { - ulong reg; - reg = read_p15_c1(); - cp_delay(); - write_p15_c1(reg & ~C1_IC); + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg & ~C1_IC); } -int icache_status(void) +int icache_status (void) { - return (read_p15_c1() & C1_IC) != 0; + return (read_p15_c1 () & C1_IC) != 0; } -void dcache_enable(void) +void dcache_enable (void) { - ulong reg; - reg = read_p15_c1(); - cp_delay(); - write_p15_c1(reg | C1_DC); + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + write_p15_c1 (reg | C1_DC); } -void dcache_disable(void) +void dcache_disable (void) { - ulong reg; - reg = read_p15_c1(); - cp_delay(); - reg &= ~C1_DC; - write_p15_c1(reg); + ulong reg; + + reg = read_p15_c1 (); + cp_delay (); + reg &= ~C1_DC; + write_p15_c1 (reg); } -int dcache_status(void) +int dcache_status (void) { - return (read_p15_c1() & C1_DC) != 0; + return (read_p15_c1 () & C1_DC) != 0; } #endif diff --git a/cpu/mpc8xx/status_led.c b/cpu/mpc8xx/status_led.c index c21682d..d8aaeec 100644 --- a/cpu/mpc8xx/status_led.c +++ b/cpu/mpc8xx/status_led.c @@ -65,6 +65,13 @@ led_dev_t led_dev[] = { 0, }, #endif +#if defined(STATUS_LED_BIT3) + { STATUS_LED_BIT3, + STATUS_LED_STATE3, + STATUS_LED_PERIOD3, + 0, + }, +#endif }; #define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t)) diff --git a/cpu/sa1100/cpu.c b/cpu/sa1100/cpu.c index 34850c2..2606862 100644 --- a/cpu/sa1100/cpu.c +++ b/cpu/sa1100/cpu.c @@ -33,110 +33,115 @@ #include #include -void cpu_init(bd_t *bd) +int cpu_init (gd_t *gd) { - /* - * setup up stack if necessary - */ + /* + * setup up stack if necessary + */ #ifdef CONFIG_USE_IRQ - IRQ_STACK_START = _armboot_end + - CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4; - FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ; - _armboot_real_end = FIQ_STACK_START + 4; + IRQ_STACK_START = _armboot_end + + CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4; + FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ; + _armboot_real_end = FIQ_STACK_START + 4; #else - _armboot_real_end = _armboot_end + CONFIG_STACKSIZE; + _armboot_real_end = _armboot_end + CONFIG_STACKSIZE; #endif + return (0); } -void cleanup_before_linux(bd_t *bd) +int cleanup_before_linux (gd_t * gd) { - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * just disable everything that can disturb booting linux - */ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * just disable everything that can disturb booting linux + */ - unsigned long i; + unsigned long i; - disable_interrupts(); + disable_interrupts (); - /* turn off I-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); - i &= ~0x1000; - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); + /* turn off I-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~0x1000; + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - /* flush I-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i)); + /* flush I-cache */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); + + return (0); } -void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_reset (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]) { - extern void reset_cpu(ulong addr); + extern void reset_cpu (ulong addr); + + printf ("resetting ...\n"); - printf("reseting ...\n"); + udelay (50000); /* wait 50 ms */ + disable_interrupts (); + reset_cpu (0); - udelay(50000); /* wait 50 ms */ - disable_interrupts(); - reset_cpu(0); - /*NOTREACHED*/ + /*NOTREACHED*/ + return (0); } /* taken from blob */ -void icache_enable(void) +void icache_enable (void) { - register u32 i; + register u32 i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - /* set i-cache */ - i |= 0x1000; + /* set i-cache */ + i |= 0x1000; - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } -void icache_disable(void) +void icache_disable (void) { - register u32 i; + register u32 i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - /* clear i-cache */ - i &= ~0x1000; + /* clear i-cache */ + i &= ~0x1000; - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - /* flush i-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i)); + /* flush i-cache */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); } -int icache_status(void) +int icache_status (void) { - register u32 i; + register u32 i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - /* return bit */ - return (i & 0x1000); + /* return bit */ + return (i & 0x1000); } /* we will never enable dcache, because we have to setup MMU first */ -void dcache_enable(void) +void dcache_enable (void) { - return; + return; } -void dcache_disable(void) +void dcache_disable (void) { - return; + return; } -int dcache_status(void) +int dcache_status (void) { - return 0; /* always off */ + return 0; /* always off */ } diff --git a/cpu/xscale/cpu.c b/cpu/xscale/cpu.c index 34850c2..11c9e00 100644 --- a/cpu/xscale/cpu.c +++ b/cpu/xscale/cpu.c @@ -33,110 +33,115 @@ #include #include -void cpu_init(bd_t *bd) +int cpu_init (gd_t *gd) { - /* - * setup up stack if necessary - */ + /* + * setup up stack if necessary + */ #ifdef CONFIG_USE_IRQ - IRQ_STACK_START = _armboot_end + - CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4; - FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ; - _armboot_real_end = FIQ_STACK_START + 4; + IRQ_STACK_START = _armboot_end + + CONFIG_STACKSIZE + CONFIG_STACKSIZE_IRQ - 4; + FIQ_STACK_START = IRQ_STACK_START + CONFIG_STACKSIZE_FIQ; + _armboot_real_end = FIQ_STACK_START + 4; #else - _armboot_real_end = _armboot_end + CONFIG_STACKSIZE; + _armboot_real_end = _armboot_end + CONFIG_STACKSIZE; #endif + return (0); } -void cleanup_before_linux(bd_t *bd) +int cleanup_before_linux (gd_t *dummy) { - /* - * this function is called just before we call linux - * it prepares the processor for linux - * - * just disable everything that can disturb booting linux - */ + /* + * this function is called just before we call linux + * it prepares the processor for linux + * + * just disable everything that can disturb booting linux + */ - unsigned long i; + unsigned long i; - disable_interrupts(); + disable_interrupts (); - /* turn off I-cache */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); - i &= ~0x1000; - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); + /* turn off I-cache */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); + i &= ~0x1000; + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - /* flush I-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i)); + /* flush I-cache */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); + + return (0); } -void do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +int do_reset (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]) { - extern void reset_cpu(ulong addr); + extern void reset_cpu (ulong addr); + + printf ("reseting ...\n"); - printf("reseting ...\n"); + udelay (50000); /* wait 50 ms */ + disable_interrupts (); + reset_cpu (0); - udelay(50000); /* wait 50 ms */ - disable_interrupts(); - reset_cpu(0); - /*NOTREACHED*/ + /*NOTREACHED*/ + return (0); } /* taken from blob */ -void icache_enable(void) +void icache_enable (void) { - register u32 i; + register u32 i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - /* set i-cache */ - i |= 0x1000; + /* set i-cache */ + i |= 0x1000; - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); } -void icache_disable(void) +void icache_disable (void) { - register u32 i; + register u32 i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - /* clear i-cache */ - i &= ~0x1000; + /* clear i-cache */ + i &= ~0x1000; - /* write back to control register */ - asm ("mcr p15, 0, %0, c1, c0, 0": : "r" (i)); + /* write back to control register */ + asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); - /* flush i-cache */ - asm ("mcr p15, 0, %0, c7, c5, 0": : "r" (i)); + /* flush i-cache */ + asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (i)); } -int icache_status(void) +int icache_status (void) { - register u32 i; + register u32 i; - /* read control register */ - asm ("mrc p15, 0, %0, c1, c0, 0": "=r" (i)); + /* read control register */ + asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); - /* return bit */ - return (i & 0x1000); + /* return bit */ + return (i & 0x1000); } /* we will never enable dcache, because we have to setup MMU first */ -void dcache_enable(void) +void dcache_enable (void) { - return; + return; } -void dcache_disable(void) +void dcache_disable (void) { - return; + return; } -int dcache_status(void) +int dcache_status (void) { - return 0; /* always off */ + return 0; /* always off */ } diff --git a/doc/README.commands b/doc/README.commands index 58208c9..4a7fecd 100644 --- a/doc/README.commands +++ b/doc/README.commands @@ -40,6 +40,7 @@ erase 3 fccinfo 3 fdcboot 4 flinfo 3 +fpga 4 getdcr 6 # IBM 4XX DCR registers go 2 help 1 diff --git a/include/altera.h b/include/altera.h new file mode 100644 index 0000000..da18d73 --- /dev/null +++ b/include/altera.h @@ -0,0 +1,73 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 + +#ifndef _ALTERA_H_ +#define _ALTERA_H_ + +/* + * Note that this is just Altera FPGA interface boilerplate. + * There is no support for Altera devices yet. + * + * See include/xilinx.h for a working example. + */ + +/* In your board's config.h file you should define CONFIG_FPGA as such: + * #define CONFIG_FPGA (CFG_ALTERA_xxx | CFG_ALTERA_IF_xxx ) + */ + +/* Altera Model definitions */ +#define CFG_ALTERA_xxxx ( CFG_FPGA_ALTERA | CFG_FPGA_DEV( 0x1 )) +/* Add new models here */ + +/* Altera Interface definitions */ +#define CFG_ALTERA_IF_xxx CFG_FPGA_IF( 0x1 ) +/* Add new interfaces here */ + +typedef enum { /* typedef Altera_iface */ + min_altera_iface_type, /* insert all new types after this */ +/* Add new interfaces here */ + max_altera_iface_type /* insert all new types before this */ +} Altera_iface; /* end, typedef Altera_iface */ + +typedef enum { /* typedef Altera_Family */ + min_altera_type, /* insert all new types after this */ +/* Add new models here */ + max_altera_type /* insert all new types before this */ +} Altera_Family; /* end, typedef Altera_Family */ + +typedef struct { /* typedef Altera_desc */ + Altera_Family family; /* part type */ + Altera_iface iface; /* interface type */ + size_t size; /* bytes of data part can accept */ + void * base; /* base interface address */ +} Altera_desc; /* end, typedef Altera_desc */ + +extern int altera_load( Altera_desc *desc, void *image, size_t size ); +extern int altera_dump( Altera_desc *desc, void *buf, size_t bsize ); +extern int altera_info( Altera_desc *desc ); +extern int altera_reloc( Altera_desc *desc, ulong reloc_off ); + +#endif /* _ALTERA_H_ */ diff --git a/include/asm-arm/global_data.h b/include/asm-arm/global_data.h index 109d309..49d9286 100644 --- a/include/asm-arm/global_data.h +++ b/include/asm-arm/global_data.h @@ -33,4 +33,19 @@ * Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t) */ +typedef struct global_data { + bd_t *bd; + unsigned long baudrate; +#if 0 + unsigned long cpu_clk; /* CPU clock in Hz! */ + unsigned long bus_clk; + unsigned long ram_size; /* RAM size */ + unsigned long reloc_off; /* Relocation Offset */ + unsigned long reset_status; /* reset status register at boot */ + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + unsigned long have_console; /* serial_init() was called */ +#endif +} gd_t; + #endif /* __ASM_GBL_DATA_H */ diff --git a/include/asm-arm/ppcboot-arm.h b/include/asm-arm/ppcboot-arm.h new file mode 100644 index 0000000..f9d5b97 --- /dev/null +++ b/include/asm-arm/ppcboot-arm.h @@ -0,0 +1,195 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * 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 + */ + +#ifndef _PPCBOOT_ARM_H_ +#define _PPCBOOT_ARM_H_ 1 + +/* for the following variables, see start.S */ +extern ulong _armboot_start; /* code start */ +extern ulong _armboot_end; /* code end */ +extern ulong IRQ_STACK_START; /* top of IRQ stack */ +extern ulong FIQ_STACK_START; /* top of FIQ stack */ +extern ulong _armboot_real_end; /* first usable RAM address */ + +/* ------------------------------------------------------------ */ +/* Here is a list of some prototypes which are incompatible to */ +/* the PPCBoot implementation */ +/* To be fixed! */ +/* ------------------------------------------------------------ */ +/* common/cmd_nvedit.c */ +int env_init (gd_t *); +void env_relocate (gd_t *); +char *getenv (bd_t *bd, uchar *); +void setenv (bd_t *bd, char *, char *); + +/* cpu/.../cpu.c */ +void cpu_init(bd_t *bd); +void cleanup_before_linux(bd_t *bd); + +/* board/.../... */ +int board_init(bd_t *); +int dram_init(bd_t *bd); + +/* arm/display_options.c */ +void display_banner(bd_t *bd); +void display_dram_config(bd_t *bd); +void display_flash_config(bd_t *bd, ulong size); + +/* cpu/.../interrupt.c */ +void reset_timer_masked (void); +ulong get_timer_masked (void); +void udelay_masked (unsigned long usec); + +#if 0 /*------------------------------------------------------------*/ +/* arm/crc32.c */ +ulong crc32 (ulong, const unsigned char *, uint); +ulong crc32_no_comp (ulong crc, const unsigned char *, uint); + +/* + * Don't define some stuff private to armboot target code + */ +#ifndef HOST_TOOLS + +/* board/.../env.c */ +int board_env_getchar(bd_t * bd, int index, uchar *c); +int board_env_save (bd_t * bd, env_t *data, int size); +int board_env_copy (bd_t * bd, env_t *data, int size); +uchar * board_env_getaddr(bd_t * bd, int index); + + +/* + * Function Prototypes + */ +void hang (void); +void start_armboot (void); +void main_loop (bd_t *); +int run_command (const char *cmd, bd_t *, int flag); +int readline (const char *const prompt); +void reset_cmd_timeout(void); + + +/* arm/string.c */ +char * strcpy (char * dest,const char *src); +char * strncpy (char * dest,const char *src, size_t count); +size_t strlen (const char *); +size_t strnlen (const char * s, size_t count); +int strncmp (const char * cs, const char * ct, size_t count); +int strcmp (const char * cs, const char * ct); +void * memcpy (void * dest, const void *src, size_t count); +int memcmp (const void * dest, const void *src, size_t count); +void * memset (void * s, char c, size_t count); +void * memmove (void * dest, const void *src, size_t count); +char * strchr (const char * s, int c); + +/* arm/vsprintf.c */ +ulong simple_strtoul (const char *cp,char **endp,unsigned int base); +long simple_strtol (const char *cp,char **endp,unsigned int base); +void panic (const char *fmt, ...); +int sprintf (char * buf, const char *fmt, ...); +int vsprintf (char *buf, const char *fmt, va_list args); + +void udelay (unsigned long); + +int ctrlc (void); +int had_ctrlc (void); +void clear_ctrlc (void); +int disable_ctrlc (int); + +int console_assign (int file, char *devname); + +/* */ +int icache_status (void); +void icache_enable (void); +void icache_disable(void); +int dcache_status (void); +void dcache_enable (void); +void dcache_disable(void); + +/* common/cmd_bootm.c */ +void print_image_hdr (image_header_t *hdr); + +/* cpu/.../interrupt.c */ +void enable_interrupts (void); +int disable_interrupts (void); +void interrupt_init (bd_t *bd); +void reset_timer (void); +ulong get_timer (ulong base); +void set_timer (ulong t); + +extern ulong load_addr; + +/* + * STDIO based functions (can always be used) + */ + +/* serial stuff */ +void serial_printf (const char *fmt, ...); + +/* stdin */ +int getc(void); +int tstc(void); + +/* stdout */ +void putc(const char c); +void puts(const char *s); +void printf(const char *fmt, ...); + +/* stderr */ +#define eputc(c) fputc(stderr, c) +#define eputs(s) fputs(stderr, s) +#define eprintf(fmt,args...) fprintf(stderr,fmt ,##args) + +/* + * FILE based functions (can only be used AFTER relocation!) + */ + +#define stdin 0 +#define stdout 1 +#define stderr 2 +#define MAX_FILES 3 + +void fprintf(int file, const char *fmt, ...); +void fputs(int file, const char *s); +void fputc(int file, const char c); +int ftstc(int file); +int fgetc(int file); + +/* Byte swapping stuff */ +#define SWAP16(x) ((((x) & 0xff) << 8) | ((x) >> 8)) +#define SWAP16c(x) ((((x) & 0xff) << 8) | ((x) >> 8)) +#define SWAP32(x) ( \ + (((x) >> 24) & 0x000000ff) | \ + (((x) >> 8) & 0x0000ff00) | \ + (((x) << 8) & 0x00ff0000) | \ + (((x) << 24) & 0xff000000) ) + +#endif /* HOST_TOOLS */ +#endif /* 0 ------------------------------------------------------------*/ + + +#endif /* _PPCBOOT_ARM_H_ */ diff --git a/include/asm-arm/ppcboot.h b/include/asm-arm/ppcboot.h index a704675..259f4d7 100644 --- a/include/asm-arm/ppcboot.h +++ b/include/asm-arm/ppcboot.h @@ -47,165 +47,4 @@ typedef struct bd_info { #define bi_env_data bi_env->data #define bi_env_crc bi_env->crc -/* for the following variables, see start.S */ -extern ulong _armboot_start; /* code start */ -extern ulong _armboot_end; /* code end */ -extern ulong IRQ_STACK_START; /* top of IRQ stack */ -extern ulong FIQ_STACK_START; /* top of FIQ stack */ -extern ulong _armboot_real_end; /* first usable RAM address */ - -/* ------------------------------------------------------------ */ -/* Here is a list of some prototypes which are incompatible to */ -/* the PPCBoot implementation */ -/* To be fixed! */ -/* ------------------------------------------------------------ */ -/* common/cmd_nvedit.c */ -int env_init (gd_t *); -void env_relocate (gd_t *); -char *getenv (bd_t *bd, uchar *); -void setenv (bd_t *bd, char *, char *); - -/* cpu/.../cpu.c */ -void cpu_init(bd_t *bd); -void cleanup_before_linux(bd_t *bd); - -/* board/.../... */ -int board_init(bd_t *); -int dram_init(bd_t *bd); - -/* arm/display_options.c */ -void display_banner(bd_t *bd); -void display_dram_config(bd_t *bd); -void display_flash_config(bd_t *bd, ulong size); - -/* cpu/.../interrupt.c */ -void reset_timer_masked (void); -ulong get_timer_masked (void); -void udelay_masked (unsigned long usec); - -#if 0 /*------------------------------------------------------------*/ -/* arm/crc32.c */ -ulong crc32 (ulong, const unsigned char *, uint); -ulong crc32_no_comp (ulong crc, const unsigned char *, uint); - -/* - * Don't define some stuff private to armboot target code - */ -#ifndef HOST_TOOLS - -/* board/.../env.c */ -int board_env_getchar(bd_t * bd, int index, uchar *c); -int board_env_save (bd_t * bd, env_t *data, int size); -int board_env_copy (bd_t * bd, env_t *data, int size); -uchar * board_env_getaddr(bd_t * bd, int index); - -/* - * Function Prototypes - */ -void hang (void); -void start_armboot (void); -void main_loop (bd_t *); -int run_command (const char *cmd, bd_t *, int flag); -int readline (const char *const prompt); -void reset_cmd_timeout(void); - - -/* arm/string.c */ -char * strcpy (char * dest,const char *src); -char * strncpy (char * dest,const char *src, size_t count); -size_t strlen (const char *); -size_t strnlen (const char * s, size_t count); -int strncmp (const char * cs, const char * ct, size_t count); -int strcmp (const char * cs, const char * ct); -void * memcpy (void * dest, const void *src, size_t count); -int memcmp (const void * dest, const void *src, size_t count); -void * memset (void * s, char c, size_t count); -void * memmove (void * dest, const void *src, size_t count); -char * strchr (const char * s, int c); - -/* arm/vsprintf.c */ -ulong simple_strtoul (const char *cp,char **endp,unsigned int base); -long simple_strtol (const char *cp,char **endp,unsigned int base); -void panic (const char *fmt, ...); -int sprintf (char * buf, const char *fmt, ...); -int vsprintf (char *buf, const char *fmt, va_list args); - -void udelay (unsigned long); - -int ctrlc (void); -int had_ctrlc (void); -void clear_ctrlc (void); -int disable_ctrlc (int); - -int console_assign (int file, char *devname); - -/* */ -int icache_status (void); -void icache_enable (void); -void icache_disable(void); -int dcache_status (void); -void dcache_enable (void); -void dcache_disable(void); - -/* common/cmd_bootm.c */ -void print_image_hdr (image_header_t *hdr); - -/* cpu/.../interrupt.c */ -void enable_interrupts (void); -int disable_interrupts (void); -void interrupt_init (bd_t *bd); -void reset_timer (void); -ulong get_timer (ulong base); -void set_timer (ulong t); - -extern ulong load_addr; - -/* - * STDIO based functions (can always be used) - */ - -/* serial stuff */ -void serial_printf (const char *fmt, ...); - -/* stdin */ -int getc(void); -int tstc(void); - -/* stdout */ -void putc(const char c); -void puts(const char *s); -void printf(const char *fmt, ...); - -/* stderr */ -#define eputc(c) fputc(stderr, c) -#define eputs(s) fputs(stderr, s) -#define eprintf(fmt,args...) fprintf(stderr,fmt ,##args) - -/* - * FILE based functions (can only be used AFTER relocation!) - */ - -#define stdin 0 -#define stdout 1 -#define stderr 2 -#define MAX_FILES 3 - -void fprintf(int file, const char *fmt, ...); -void fputs(int file, const char *s); -void fputc(int file, const char c); -int ftstc(int file); -int fgetc(int file); - -/* Byte swapping stuff */ -#define SWAP16(x) ((((x) & 0xff) << 8) | ((x) >> 8)) -#define SWAP16c(x) ((((x) & 0xff) << 8) | ((x) >> 8)) -#define SWAP32(x) ( \ - (((x) >> 24) & 0x000000ff) | \ - (((x) >> 8) & 0x0000ff00) | \ - (((x) << 8) & 0x00ff0000) | \ - (((x) << 24) & 0xff000000) ) - -#endif /* HOST_TOOLS */ -#endif /* 0 ------------------------------------------------------------*/ - #endif /* _PPCBOOT_H_ */ diff --git a/include/cmd_confdefs.h b/include/cmd_confdefs.h index 0688754..0d91575 100644 --- a/include/cmd_confdefs.h +++ b/include/cmd_confdefs.h @@ -71,6 +71,7 @@ #define CFG_CMD_JFFS2 0x0000001000000000 /* JFFS2 Support */ #define CFG_CMD_DTT 0x0000002000000000 /* Digital Therm and Thermostat */ #define CFG_CMD_SDRAM 0x0000004000000000 /* SDRAM DIMM SPD info printout */ +#define CFG_CMD_FPGA 0x0000080000000000 /* FPGA configuration Support */ #define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFF /* ALL commands */ diff --git a/include/cmd_fpga.h b/include/cmd_fpga.h new file mode 100644 index 0000000..b34b3da --- /dev/null +++ b/include/cmd_fpga.h @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2001 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 + * + */ + +/* + * FPGA support + */ +#ifndef _CMD_FPGA_H +#define _CMD_FPGA_H + +#include +#include + +#if defined(CONFIG_FPGA) && (CONFIG_COMMANDS & CFG_CMD_FPGA) + +#define CMD_TBL_FPGA MK_CMD_TBL_ENTRY( \ + "fpga", 4, 6, 1, do_fpga, \ + "fpga - loadable FPGA image support\n", \ + "fpga [operation type] [device number] [image address] [image size]\n" \ + "fpga operations:\n" \ + "\tinfo\tlist known device information.\n" \ + "\tload\tLoad device from memory buffer.\n" \ + "\tdump\tLoad device to memory buffer.\n" \ +), + +extern int do_fpga (cmd_tbl_t *cmdtp, gd_t *gd, int flag, int argc, char *argv[]); + +#else +#define CMD_TBL_FPGA +#endif /* CONFIG_FPGA && CONFIG_COMMANDS & CFG_CMD_FPGA */ + +#endif /* _CMD_FPGA_H */ diff --git a/include/common.h b/include/common.h index 6e4a8b5..ef233e1 100644 --- a/include/common.h +++ b/include/common.h @@ -115,7 +115,7 @@ void print_image_hdr (image_header_t *hdr); extern ulong load_addr; /* Default Load Address */ -#ifdef CONFIG_PPC /* ARM version in armboot.h - to be fixed! */ +#ifdef CONFIG_PPC /* ARM version to be fixed! */ /* common/cmd_nvedit.c */ int env_init (gd_t *); void env_relocate (gd_t *); @@ -124,6 +124,9 @@ int getenv_r (uchar *name, uchar *buf, unsigned len); int saveenv (void); void inline setenv (char *, char *); #endif /* CONFIG_PPC */ +#ifdef CONFIG_ARM +# include /* ARM version to be fixed! */ +#endif /* CONFIG_ARM */ void pci_init (gd_t *); void pciinfo (int, int); diff --git a/include/fpga.h b/include/fpga.h new file mode 100644 index 0000000..782b58e --- /dev/null +++ b/include/fpga.h @@ -0,0 +1,81 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 /* for ulong typedef */ + +#ifndef _FPGA_H_ +#define _FPGA_H_ + +#ifndef CONFIG_MAX_FPGA_DEVICES +#define CONFIG_MAX_FPGA_DEVICES 5 +#endif + +/* these probably belong somewhere else */ +#ifndef FALSE +#define FALSE (0) +#endif +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +/* CONFIG_FPGA bit assignments */ +#define CFG_FPGA_MAN(x) (x) +#define CFG_FPGA_DEV(x) ((x) << 8 ) +#define CFG_FPGA_IF(x) ((x) << 16 ) + +/* FPGA Manufacturer bits in CONFIG_FPGA */ +#define CFG_FPGA_XILINX CFG_FPGA_MAN( 0x1 ) +#define CFG_FPGA_ALTERA CFG_FPGA_MAN( 0x2 ) + + +/* fpga_xxxx function return value definitions */ +#define FPGA_SUCCESS 0 +#define FPGA_FAIL -1 + +/* device numbers must be non-negative */ +#define FPGA_INVALID_DEVICE -1 + +/* root data type defintions */ +typedef enum { /* typedef fpga_type */ + fpga_min_type, /* range check value */ + fpga_xilinx, /* Xilinx Family) */ + fpga_altera, /* unimplemented */ + fpga_undefined /* invalid range check value */ +} fpga_type; /* end, typedef fpga_type */ + +typedef struct { /* typedef fpga_desc */ + fpga_type devtype; /* switch value to select sub-functions */ + void * devdesc; /* real device descriptor */ +} fpga_desc; /* end, typedef fpga_desc */ + + +/* root function definitions */ +extern void fpga_init( ulong reloc_off ); +extern int fpga_add( fpga_type devtype, void *desc ); +extern const int fpga_count( void ); +extern int fpga_load( int devnum, void *buf, size_t bsize ); +extern int fpga_dump( int devnum, void *buf, size_t bsize ); +extern int fpga_info( int devnum ); + +#endif /* _FPGA_H_ */ diff --git a/include/spartan2.h b/include/spartan2.h new file mode 100644 index 0000000..2f98f96 --- /dev/null +++ b/include/spartan2.h @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 + * + */ + +#ifndef _SPARTAN2_H_ +#define _SPARTAN2_H_ + +#include + +extern int Spartan2_load( Xilinx_desc *desc, void *image, size_t size ); +extern int Spartan2_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +extern int Spartan2_info( Xilinx_desc *desc ); +extern int Spartan2_reloc( Xilinx_desc *desc, ulong reloc_off ); + +/* Slave Parallel Implementation function table */ +typedef struct { + Xilinx_pre_fn pre; + Xilinx_pgm_fn pgm; + Xilinx_init_fn init; + Xilinx_err_fn err; + Xilinx_done_fn done; + Xilinx_clk_fn clk; + Xilinx_cs_fn cs; + Xilinx_wr_fn wr; + Xilinx_rdata_fn rdata; + Xilinx_wdata_fn wdata; + Xilinx_busy_fn busy; + Xilinx_abort_fn abort; + Xilinx_post_fn post; + int relocated; +} Xilinx_Spartan2_Slave_Parallel_fns; + +/* Slave Serial Implementation function table */ +typedef struct { + Xilinx_pgm_fn pgm; + Xilinx_clk_fn clk; + Xilinx_rdata_fn rdata; + Xilinx_wdata_fn wdata; + int relocated; +} Xilinx_Spartan2_Slave_Serial_fns; + +/* Device Image Sizes + *********************************************************************/ +/* Spartan-II (2.5V) */ +#define XILINX_XC2S15_SIZE 197728/8 +#define XILINX_XC2S30_SIZE 336800/8 +#define XILINX_XC2S50_SIZE 559232/8 +#define XILINX_XC2S100_SIZE 781248/8 +#define XILINX_XC2S150_SIZE 1040128/8 + +/* Descriptor Macros + *********************************************************************/ +/* Spartan-II devices */ +#define XILINX_XC2S15_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan2, iface, XILINX_XC2S15_SIZE, fn_table, cookie } + +#define XILINX_XC2S30_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan2, iface, XILINX_XC2S30_SIZE, fn_table, cookie } + +#define XILINX_XC2S50_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan2, iface, XILINX_XC2S50_SIZE, fn_table, cookie } + +#define XILINX_XC2S100_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan2, iface, XILINX_XC2S100_SIZE, fn_table, cookie } + +#define XILINX_XC2S150_DESC(iface, fn_table, cookie) \ +{ Xilinx_Spartan2, iface, XILINX_XC2S150_SIZE, fn_table, cookie } + +#endif /* _SPARTAN2_H_ */ + diff --git a/include/virtex2.h b/include/virtex2.h new file mode 100644 index 0000000..8c0383e --- /dev/null +++ b/include/virtex2.h @@ -0,0 +1,120 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.com. + * Keith Outwater, keith_outwater@mvis.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 + * + */ + +#ifndef _VIRTEX2_H_ +#define _VIRTEX2_H_ + +#include + +extern int Virtex2_load( Xilinx_desc *desc, void *image, size_t size ); +extern int Virtex2_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +extern int Virtex2_info( Xilinx_desc *desc ); +extern int Virtex2_reloc( Xilinx_desc *desc, ulong reloc_off ); + +/* + * Slave SelectMap Implementation function table. + */ +typedef struct { + Xilinx_pre_fn pre; + Xilinx_pgm_fn pgm; + Xilinx_init_fn init; + Xilinx_err_fn err; + Xilinx_done_fn done; + Xilinx_clk_fn clk; + Xilinx_cs_fn cs; + Xilinx_wr_fn wr; + Xilinx_rdata_fn rdata; + Xilinx_wdata_fn wdata; + Xilinx_busy_fn busy; + Xilinx_abort_fn abort; + Xilinx_post_fn post; + int relocated; +} Xilinx_Virtex2_Slave_SelectMap_fns; + +/* Slave Serial Implementation function table */ +typedef struct { + Xilinx_pgm_fn pgm; + Xilinx_clk_fn clk; + Xilinx_rdata_fn rdata; + Xilinx_wdata_fn wdata; + int relocated; +} Xilinx_Virtex2_Slave_Serial_fns; + +/* Device Image Sizes (in bytes) + *********************************************************************/ +#define XILINX_XC2V40_SIZE (338208 / 8) +#define XILINX_XC2V80_SIZE (597408 / 8) +#define XILINX_XC2V250_SIZE (1591584 / 8) +#define XILINX_XC2V500_SIZE (2557857 / 8) +#define XILINX_XC2V1000_SIZE (3749408 / 8) +#define XILINX_XC2V1500_SIZE (5166240 / 8) +#define XILINX_XC2V2000_SIZE (6808352 / 8) +#define XILINX_XC2V3000_SIZE (9589408 / 8) +#define XILINX_XC2V4000_SIZE (14220192 / 8) +#define XILINX_XC2V6000_SIZE (19752096 / 8) +#define XILINX_XC2V8000_SIZE (26185120 / 8) +#define XILINX_XC2V10000_SIZE (33519264 / 8) + +/* Descriptor Macros + *********************************************************************/ +#define XILINX_XC2V40_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V40_SIZE, fn_table, cookie } + +#define XILINX_XC2V80_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V80_SIZE, fn_table, cookie } + +#define XILINX_XC2V250_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V250_SIZE, fn_table, cookie } + +#define XILINX_XC2V500_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V500_SIZE, fn_table, cookie } + +#define XILINX_XC2V1000_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V1000_SIZE, fn_table, cookie } + +#define XILINX_XC2V1500_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V1500_SIZE, fn_table, cookie } + +#define XILINX_XC2V2000_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V2000_SIZE, fn_table, cookie } + +#define XILINX_XC2V3000_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V3000_SIZE, fn_table, cookie } + +#define XILINX_XC2V4000_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V4000_SIZE, fn_table, cookie } + +#define XILINX_XC2V6000_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V6000_SIZE, fn_table, cookie } + +#define XILINX_XC2V8000_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V8000_SIZE, fn_table, cookie } + +#define XILINX_XC2V10000_DESC(iface, fn_table, cookie) \ +{ Xilinx_Virtex2, iface, XILINX_XC2V10000_SIZE, fn_table, cookie } + +#endif /* _VIRTEX2_H_ */ + +/* vim: set ts=4 tw=78: */ diff --git a/include/xilinx.h b/include/xilinx.h new file mode 100644 index 0000000..73d5434 --- /dev/null +++ b/include/xilinx.h @@ -0,0 +1,102 @@ +/* + * (C) Copyright 2002 + * Rich Ireland, Enterasys Networks, rireland@enterasys.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 + +#ifndef _XILINX_H_ +#define _XILINX_H_ + +/* Xilinx Model definitions + *********************************************************************/ +#define CFG_SPARTAN2 CFG_FPGA_DEV( 0x1 ) +#define CFG_VIRTEX_E CFG_FPGA_DEV( 0x2 ) +#define CFG_VIRTEX2 CFG_FPGA_DEV( 0x4 ) +#define CFG_XILINX_SPARTAN2 (CFG_FPGA_XILINX | CFG_SPARTAN2) +#define CFG_XILINX_VIRTEX_E (CFG_FPGA_XILINX | CFG_VIRTEX_E) +#define CFG_XILINX_VIRTEX2 (CFG_FPGA_XILINX | CFG_VIRTEX2) +/* XXX - Add new models here */ + + +/* Xilinx Interface definitions + *********************************************************************/ +#define CFG_XILINX_IF_SS CFG_FPGA_IF( 0x1 ) /* slave serial */ +#define CFG_XILINX_IF_MS CFG_FPGA_IF( 0x2 ) /* master serial */ +#define CFG_XILINX_IF_SP CFG_FPGA_IF( 0x4 ) /* slave parallel */ +#define CFG_XILINX_IF_JTAG CFG_FPGA_IF( 0x8 ) /* jtag */ +#define CFG_XILINX_IF_MSM CFG_FPGA_IF( 0x10 ) /* master selectmap */ +#define CFG_XILINX_IF_SSM CFG_FPGA_IF( 0x20 ) /* slave selectmap */ + +/* Xilinx types + *********************************************************************/ +typedef enum { /* typedef Xilinx_iface */ + min_xilinx_iface_type, /* low range check value */ + slave_serial, /* serial data and external clock */ + master_serial, /* serial data w/ internal clock (not used) */ + slave_parallel, /* parallel data w/ external latch */ + jtag_mode, /* jtag/tap serial (not used ) */ + master_selectmap, /* master SelectMap (virtex2) */ + slave_selectmap, /* slave SelectMap (virtex2) */ + max_xilinx_iface_type /* insert all new types before this */ +} Xilinx_iface; /* end, typedef Xilinx_iface */ + +typedef enum { /* typedef Xilinx_Family */ + min_xilinx_type, /* low range check value */ + Xilinx_Spartan2, /* Spartan-II Family */ + Xilinx_VirtexE, /* Virtex-E Family */ + Xilinx_Virtex2, /* Virtex2 Family */ + max_xilinx_type /* insert all new types before this */ +} Xilinx_Family; /* end, typedef Xilinx_Family */ + +typedef struct { /* typedef Xilinx_desc */ + Xilinx_Family family; /* part type */ + Xilinx_iface iface; /* interface type */ + size_t size; /* bytes of data part can accept */ + void * iface_fns; /* interface function table */ + int cookie; /* implementation specific cookie */ +} Xilinx_desc; /* end, typedef Xilinx_desc */ + +/* Generic Xilinx Functions + *********************************************************************/ +extern int xilinx_load( Xilinx_desc *desc, void *image, size_t size ); +extern int xilinx_dump( Xilinx_desc *desc, void *buf, size_t bsize ); +extern int xilinx_info( Xilinx_desc *desc ); +extern int xilinx_reloc( Xilinx_desc *desc, ulong reloc_offset ); + +/* Board specific implementation specific function types + *********************************************************************/ +typedef int (*Xilinx_pgm_fn)( int assert_pgm, int flush, int cookie ); +typedef int (*Xilinx_init_fn)( int cookie ); +typedef int (*Xilinx_err_fn)( int cookie ); +typedef int (*Xilinx_done_fn)( int cookie ); +typedef int (*Xilinx_clk_fn)( int assert_clk, int flush, int cookie ); +typedef int (*Xilinx_cs_fn)( int assert_cs, int flush, int cookie ); +typedef int (*Xilinx_wr_fn)( int assert_write, int flush, int cookie ); +typedef int (*Xilinx_rdata_fn)( unsigned char *data, int cookie ); +typedef int (*Xilinx_wdata_fn)( unsigned char data, int flush, int cookie ); +typedef int (*Xilinx_busy_fn)( int cookie ); +typedef int (*Xilinx_abort_fn)( int cookie ); +typedef int (*Xilinx_pre_fn)( int cookie ); +typedef int (*Xilinx_post_fn)( int cookie ); + +#endif /* _XILINX_H_ */ diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c index 75c884f..13e5e2e 100644 --- a/lib_arm/armlinux.c +++ b/lib_arm/armlinux.c @@ -63,6 +63,7 @@ void boot_linux(cmd_tbl_t *cmdtp, ulong data; void (*theKernel)(int zero, int arch); image_header_t *hdr = &header; + bd_t *bd = gd->bd; #ifdef CONFIG_CMDLINE_TAG char *commandline = getenv("bootargs"); #endif diff --git a/rtc/Makefile b/rtc/Makefile index 4119adb..0e1fd0f 100644 --- a/rtc/Makefile +++ b/rtc/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = librtc.a -OBJS = date.o ds1302.o ds174x.o ds1306.o ds1556.o \ +OBJS = date.o ds1302.o ds1306.o ds1337.o ds1556.o ds174x.o \ m41t11.o m48t35ax.o mc146818.o mk48t59.o \ mpc8xx.o pcf8563.o diff --git a/rtc/ds1337.c b/rtc/ds1337.c new file mode 100644 index 0000000..9f0c8c0 --- /dev/null +++ b/rtc/ds1337.c @@ -0,0 +1,191 @@ +/* + * (C) Copyright 2001, 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * Keith Outwater, keith_outwater@mvis.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 + */ + +/* + * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim) + * DS1337 Real Time Clock (RTC). + */ + +#include +#include +#include +#include + +#if defined(CONFIG_RTC_DS1337) && (CONFIG_COMMANDS & CFG_CMD_DATE) + +/*---------------------------------------------------------------------*/ +#undef DEBUG_RTC + +#ifdef DEBUG_RTC +#define DEBUGR(fmt,args...) printf(fmt ,##args) +#else +#define DEBUGR(fmt,args...) +#endif +/*---------------------------------------------------------------------*/ + +/* + * RTC register addresses + */ +#define RTC_SEC_REG_ADDR 0x0 +#define RTC_MIN_REG_ADDR 0x1 +#define RTC_HR_REG_ADDR 0x2 +#define RTC_DAY_REG_ADDR 0x3 +#define RTC_DATE_REG_ADDR 0x4 +#define RTC_MON_REG_ADDR 0x5 +#define RTC_YR_REG_ADDR 0x6 +#define RTC_CTL_REG_ADDR 0x0e +#define RTC_STAT_REG_ADDR 0x0f + +/* + * RTC control register bits + */ +#define RTC_CTL_BIT_A1IE 0x1 /* Alarm 1 interrupt enable */ +#define RTC_CTL_BIT_A2IE 0x2 /* Alarm 2 interrupt enable */ +#define RTC_CTL_BIT_INTCN 0x4 /* Interrupt control */ +#define RTC_CTL_BIT_RS1 0x8 /* Rate select 1 */ +#define RTC_CTL_BIT_RS2 0x10 /* Rate select 2 */ +#define RTC_CTL_BIT_DOSC 0x80 /* Disable Oscillator */ + +/* + * RTC status register bits + */ +#define RTC_STAT_BIT_A1F 0x1 /* Alarm 1 flag */ +#define RTC_STAT_BIT_A2F 0x2 /* Alarm 2 flag */ +#define RTC_STAT_BIT_OSF 0x80 /* Oscillator stop flag */ + + +static uchar rtc_read (uchar reg); +static void rtc_write (uchar reg, uchar val); +static uchar bin2bcd (unsigned int n); +static unsigned bcd2bin (uchar c); + + +/* + * Get the current time from the RTC + */ +void rtc_get (struct rtc_time *tmp) +{ + uchar sec, min, hour, mday, wday, mon_cent, year, control, status; + + control = rtc_read (RTC_CTL_REG_ADDR); + status = rtc_read (RTC_STAT_REG_ADDR); + sec = rtc_read (RTC_SEC_REG_ADDR); + min = rtc_read (RTC_MIN_REG_ADDR); + hour = rtc_read (RTC_HR_REG_ADDR); + wday = rtc_read (RTC_DAY_REG_ADDR); + mday = rtc_read (RTC_DATE_REG_ADDR); + mon_cent = rtc_read (RTC_MON_REG_ADDR); + year = rtc_read (RTC_YR_REG_ADDR); + + DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " + "hr: %02x min: %02x sec: %02x control: %02x status: %02x\n", + year, mon_cent, mday, wday, hour, min, sec, control, status); + + if (status & RTC_STAT_BIT_OSF) { + printf ("### Warning: RTC oscillator has stopped\n"); + /* clear the OSF flag */ + rtc_write (RTC_STAT_REG_ADDR, + rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF); + } + + tmp->tm_sec = bcd2bin (sec & 0x7F); + tmp->tm_min = bcd2bin (min & 0x7F); + tmp->tm_hour = bcd2bin (hour & 0x3F); + tmp->tm_mday = bcd2bin (mday & 0x3F); + tmp->tm_mon = bcd2bin (mon_cent & 0x1F); + tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900); + tmp->tm_wday = bcd2bin ((wday - 1) & 0x07); + tmp->tm_yday = 0; + tmp->tm_isdst= 0; + + DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +} + + +/* + * Set the RTC + */ +void rtc_set (struct rtc_time *tmp) +{ + uchar century; + + DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + + rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100)); + + century = (tmp->tm_year >= 2000) ? 0x80 : 0; + rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century); + + rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1)); + rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday)); + rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour)); + rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min)); + rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec)); +} + + +/* + * Reset the RTC. We also enable the oscillator output on the + * SQW/INTB* pin and program it for 32,768 Hz output. Note that + * according to the datasheet, turning on the square wave output + * increases the current drain on the backup battery from about + * 600 nA to 2uA. + */ +void rtc_reset (void) +{ + rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2); +} + + +/* + * Helper functions + */ + +static +uchar rtc_read (uchar reg) +{ + return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg)); +} + + +static void rtc_write (uchar reg, uchar val) +{ + i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val); +} + +static unsigned bcd2bin (uchar n) +{ + return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F)); +} + +static unsigned char bin2bcd (unsigned int n) +{ + return (((n / 10) << 4) | (n % 10)); +} + +#endif /* CONFIG_RTC_DS1337 && (CFG_COMMANDS & CFG_CMD_DATE) */