Add support for LynuxWorks Kernel Downloadable Images (KDIs).
Both LynxOS and BlueCat linux KDIs are supported.
* Patch by Richard Woodruff, 25 Jul 2003:
use more reliable reset for OMAP/925T
* Patch by Nye Liu, 25 Jul 2003:
fix typo in mpc8xx.h
* Patch by Richard Woodruff, 24 Jul 2003:
Fixes for cmd_nand.c:
- Fixed null dereferece which could result in incorrect ECC values.
- Added support for devices with no Ready/Busy signal hooked up.
- Added OMAP1510 read/write protect handling.
- Fixed nand.h's ECCPOS. A conflict existed with POS5 and badblock
for non-JFFS2.
- Switched default ECC to be JFFS2.
Changes for U-Boot 0.4.5:
======================================================================
+* Patch by Scott McNutt, 21 Jul 2003:
+ Add support for LynuxWorks Kernel Downloadable Images (KDIs).
+ Both LynxOS and BlueCat linux KDIs are supported.
+
+* Patch by Richard Woodruff, 25 Jul 2003:
+ use more reliable reset for OMAP/925T
+
+* Patch by Nye Liu, 25 Jul 2003:
+ fix typo in mpc8xx.h
+
+* Patch by Richard Woodruff, 24 Jul 2003:
+ Fixes for cmd_nand.c:
+ - Fixed null dereferece which could result in incorrect ECC values.
+ - Added support for devices with no Ready/Busy signal hooked up.
+ - Added OMAP1510 read/write protect handling.
+ - Fixed nand.h's ECCPOS. A conflict existed with POS5 and badblock
+ for non-JFFS2.
+ - Switched default ECC to be JFFS2.
+
* Allow crc32 to be used at address 0x000
* Provide consistent interface to standalone applications to access
* Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD,
4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks,
LynxOS, pSOS, QNX, RTEMS, ARTOS;
- Currently supported: Linux, NetBSD, VxWorks, QNX, RTEMS, ARTOS).
+ Currently supported: Linux, NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS).
* Target CPU Architecture (Provisions for Alpha, ARM, Intel x86,
IA64, MIPS, MIPS, PowerPC, IBM S390, SuperH, Sparc, Sparc 64 Bit;
Currently supported: PowerPC).
environment.o env_common.o \
env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
flash.o fpga.o \
- hush.o kgdb.o lists.o miiphybb.o miiphyutil.o \
+ hush.o kgdb.o lists.o lynxkdi.o miiphybb.o miiphyutil.o \
s_record.o soft_i2c.o soft_spi.o spartan2.o \
usb.o usb_kbd.o usb_storage.o \
virtex2.o xilinx.o
#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
static boot_os_Fcn do_bootm_artos;
#endif
+#ifdef CONFIG_LYNXKDI
+static boot_os_Fcn do_bootm_lynxkdi;
+extern void lynxkdi_boot( image_header_t * );
+#endif
image_header_t header;
addr, len_ptr, verify);
break;
+#ifdef CONFIG_LYNXKDI
+ case IH_OS_LYNXOS:
+ do_bootm_lynxkdi (cmdtp, flag, argc, argv,
+ addr, len_ptr, verify);
+ break;
+#endif
+
case IH_OS_RTEMS:
do_bootm_rtems (cmdtp, flag, argc, argv,
addr, len_ptr, verify);
case IH_OS_RTEMS: os = "RTEMS"; break;
#ifdef CONFIG_ARTOS
case IH_OS_ARTOS: os = "ARTOS"; break;
+#endif
+#ifdef CONFIG_LYNXKDI
+ case IH_OS_LYNXOS: os = "LynxOS"; break;
#endif
default: os = "Unknown OS"; break;
}
do_bootelf(cmdtp, 0, 2, local_args);
}
#endif /* CFG_CMD_ELF */
+
+#ifdef CONFIG_LYNXKDI
+static void
+do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag,
+ int argc, char *argv[],
+ ulong addr,
+ ulong *len_ptr,
+ int verify)
+{
+ lynxkdi_boot( &header );
+}
+
+#endif /* CONFIG_LYNXKDI */
+
* borrowed heavily from:
* (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
*/
#include <common.h>
#include <linux/mtd/nand_ids.h>
#include <jffs2/jffs2.h>
+#ifdef CONFIG_OMAP1510
+void archflashwp(void *archdata, int wp);
+#endif
+
+#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
+
/*
* Definition of the out of band configuration structure
*/
#define ALLOW_ERASE_BAD_DEBUG 0
#define CONFIG_MTD_NAND_ECC /* enable ECC */
-/* #define CONFIG_MTD_NAND_ECC_JFFS2 */
+#define CONFIG_MTD_NAND_ECC_JFFS2
/* bits for nand_rw() `cmd'; or together as needed */
#define NANDRW_READ 0x01
size_t * retlen, u_char * buf);
static int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len,
size_t * retlen, const u_char * buf);
+static int NanD_WaitReady(struct nand_chip *nand, int ale_wait);
#ifdef CONFIG_MTD_NAND_ECC
static int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
static void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
ret = nand_rw(nand_dev_desc + curr_device, cmd, off, size,
&total, (u_char*)addr);
- printf ("%d bytes %s: %s\n", total,
+ printf (" %d bytes %s: %s\n", total,
(cmd & NANDRW_READ) ? "read" : "write",
ret ? "ERROR" : "OK");
size_t start, size_t len,
size_t * retlen, u_char * buf)
{
- int noecc, ret = 0, n, total = 0;
+ int ret = 0, n, total = 0;
char eccbuf[6];
/* eblk (once set) is the start of the erase block containing the
* data being processed.
}
/* The ECC will not be calculated correctly if
less than 512 is written or read */
- noecc = (start != (start | 0x1ff) + 1) || (len < 0x200);
+ /* Is request at least 512 bytes AND it starts on a proper boundry */
+ if((start != ROUND_DOWN(start, 0x200)) || (len < 0x200))
+ printf("Warning block writes should be at least 512 bytes and start on a 512 byte boundry\n");
+
if (cmd & NANDRW_READ)
ret = nand_read_ecc(nand, start,
min(len, eblk + erasesize - start),
- &n, (u_char*)buf,
- noecc ? NULL : eccbuf);
+ &n, (u_char*)buf, eccbuf);
else
ret = nand_write_ecc(nand, start,
min(len, eblk + erasesize - start),
- &n, (u_char*)buf,
- noecc ? NULL : eccbuf);
+ &n, (u_char*)buf, eccbuf);
if (ret)
break;
/* ------------------------------------------------------------------------- */
-/* This function is needed to avoid calls of the __ashrdi3 function. */
-#if 0
-static int shr(int val, int shift)
-{
- return val >> shift;
-}
-#endif
-static int NanD_WaitReady(struct nand_chip *nand)
+static int NanD_WaitReady(struct nand_chip *nand, int ale_wait)
{
/* This is inline, to optimise the common case, where it's ready instantly */
int ret = 0;
- NAND_WAIT_READY(nand);
+#ifdef NAND_NO_RB /* in config file, shorter delays currently wrap accesses */
+ if(ale_wait)
+ NAND_WAIT_READY(nand); /* do the worst case 25us wait */
+ else
+ udelay(10);
+#else /* has functional r/b signal */
+ NAND_WAIT_READY(nand);
+#endif
return ret;
}
/* Lower the CLE line */
NAND_CTL_CLRCLE(nandptr);
- return NanD_WaitReady(nand);
+#ifdef NAND_NO_RB
+ if(command == NAND_CMD_RESET){
+ u_char ret_val;
+ NanD_Command(nand, NAND_CMD_STATUS);
+ do{
+ ret_val = READ_NAND(nandptr);/* wait till ready */
+ } while((ret_val & 0x40) != 0x40);
+ }
+#endif
+ return NanD_WaitReady(nand, 0);
}
/* NanD_Address: Set the current address for the flash chip */
NAND_CTL_CLRALE(nandptr);
/* Wait for the chip to respond */
- return NanD_WaitReady(nand);
+ return NanD_WaitReady(nand, 1);
}
/* NanD_SelectChip: Select a given flash chip within the current floor */
static inline int NanD_SelectChip(struct nand_chip *nand, int chip)
{
/* Wait for it to be ready */
- return NanD_WaitReady(nand);
+ return NanD_WaitReady(nand, 0);
}
/* NanD_IdentChip: Identify a given NAND chip given {floor,chip} */
{
int i;
-#ifdef CONFIG_MTD_NAND_ECC
unsigned long nandptr = nand->IO_ADDR;
+#ifdef CONFIG_MTD_NAND_ECC
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
int ecc_bytes = (nand->oobblock == 512) ? 6 : 3;
#endif
/* Send command to actually program the data */
NanD_Command(nand, NAND_CMD_PAGEPROG);
NanD_Command(nand, NAND_CMD_STATUS);
+#ifdef NAND_NO_RB
+ { u_char ret_val;
+ do{
+ ret_val = READ_NAND(nandptr); /* wait till ready */
+ } while((ret_val & 0x40) != 0x40);
+ }
+#endif
/* See if device thinks it succeeded */
if (READ_NAND(nand->IO_ADDR) & 0x01) {
printf ("%s: Failed write, page 0x%08x, ", __FUNCTION__, page);
return -1;
}
+
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
/*
* The NAND device assumes that it is always writing to
*retlen = 0;
/* Select the NAND device */
- NAND_ENABLE_CE(nand); /* set pin low */
+#ifdef CONFIG_OMAP1510
+ archflashwp(0,0);
+#endif
+ NAND_ENABLE_CE(nand); /* set pin low */
/* Check the WP bit */
NanD_Command(nand, NAND_CMD_STATUS);
out:
/* De-select the NAND device */
NAND_DISABLE_CE(nand); /* set pin high */
-
+#ifdef CONFIG_OMAP1510
+ archflashwp(0,1);
+#endif
return ret;
}
* causing the flash device to go into busy mode, so we need
* to wait until ready 11.4.1 and Toshiba TC58256FT nands */
- ret = NanD_WaitReady(nand);
+ ret = NanD_WaitReady(nand, 1);
NAND_DISABLE_CE(nand); /* set pin high */
return ret;
NanD_Command(nand, NAND_CMD_PAGEPROG);
NanD_Command(nand, NAND_CMD_STATUS);
- /* NanD_WaitReady() is implicit in NanD_Command */
-
+#ifdef NAND_NO_RB
+ { u_char ret_val;
+ do{
+ ret_val = READ_NAND(nandptr); /* wait till ready */
+ }while((ret_val & 0x40) != 0x40);
+ }
+#endif
if (READ_NAND(nandptr) & 1) {
puts ("Error programming oob data\n");
/* There was an error */
NanD_Command(nand, NAND_CMD_PAGEPROG);
NanD_Command(nand, NAND_CMD_STATUS);
- /* NanD_WaitReady() is implicit in NanD_Command */
-
+#ifdef NAND_NO_RB
+ { u_char ret_val;
+ do{
+ ret_val = READ_NAND(nandptr); /* wait till ready */
+ } while((ret_val & 0x40) != 0x40);
+ }
+#endif
if (READ_NAND(nandptr) & 1) {
puts ("Error programming oob data\n");
/* There was an error */
nandptr = nand->IO_ADDR;
/* Select the NAND device */
- NAND_ENABLE_CE(nand); /* set pin low */
+#ifdef CONFIG_OMAP1510
+ archflashwp(0,0);
+#endif
+ NAND_ENABLE_CE(nand); /* set pin low */
/* Check the WP bit */
NanD_Command(nand, NAND_CMD_STATUS);
NanD_Command(nand, NAND_CMD_STATUS);
+#ifdef NAND_NO_RB
+ { u_char ret_val;
+ do{
+ ret_val = READ_NAND(nandptr); /* wait till ready */
+ } while((ret_val & 0x40) != 0x40);
+ }
+#endif
if (READ_NAND(nandptr) & 1) {
printf ("%s: Error erasing at 0x%lx\n",
__FUNCTION__, (long)ofs);
out:
/* De-select the NAND device */
NAND_DISABLE_CE(nand); /* set pin high */
-
+#ifdef CONFIG_OMAP1510
+ archflashwp(0,1);
+#endif
return ret;
}
/* Should never happen */
return -1;
}
+
#endif
#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
--- /dev/null
+/*
+ * Copyright (c) Orbacom Systems, Inc <www.orbacom.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include <image.h>
+
+#if defined(CONFIG_LYNXKDI)
+#include <lynxkdi.h>
+
+#if defined(CONFIG_MPC8260)
+void lynxkdi_boot ( image_header_t *hdr )
+{
+ void (*lynxkdi)(void) = (void(*)(void))hdr->ih_ep;
+ lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020;
+ bd_t *kbd;
+ DECLARE_GLOBAL_DATA_PTR;
+ u32 *psz = (u32 *)(hdr->ih_load + 0x0204);
+
+ memset( parms, 0, sizeof(*parms));
+ kbd = gd->bd;
+ parms->clock_ref = kbd->bi_busfreq;
+ parms->dramsz = kbd->bi_memsize;
+ memcpy(parms->ethaddr, kbd->bi_enetaddr, 6);
+ mtspr(SPRN_SPRG2, 0x0020);
+
+ /* Do a simple check for Bluecat so we can pass the
+ * kernel command line parameters.
+ */
+ if( le32_to_cpu(*psz) == hdr->ih_size ){
+ char *args;
+ char *cmdline = (char *)(hdr->ih_load + 0x020c);
+ int len;
+
+ printf("Booting Bluecat KDI ...\n");
+ udelay(200*1000); /* Allow serial port to flush */
+ if ((args = getenv("bootargs")) == NULL)
+ args = "";
+ /* Prepend the cmdline */
+ len = strlen(args);
+ if( len && (len + strlen(cmdline) + 2 < (0x0400 - 0x020c))) {
+ memmove( cmdline + strlen(args) + 1, cmdline, strlen(cmdline) );
+ strcpy( cmdline, args );
+ cmdline[len] = ' ';
+ }
+ }
+ else {
+ printf("Booting LynxOS KDI ...\n");
+ }
+
+ lynxkdi();
+}
+#else
+#error "Lynx KDI support not implemented for configured CPU"
+#endif
+
+#endif /* CONFIG_LYNXKDI */
+
.globl reset_cpu
reset_cpu:
ldr r1, rstctl1 /* get clkm1 reset ctl */
- mov r3, #0x0
- strh r3, [r1] /* clear it */
- mov r3, #0x8
- strh r3, [r1] /* force dsp+arm reset */
+ mov r3, #0x3 /* dsp_en + arm_rst = global reset */
+ strh r3, [r1] /* force reset */
+ mov r0, r0
_loop_forever:
b _loop_forever
rstctl1:
GOT_ENTRY(__init_end)
GOT_ENTRY(_end)
GOT_ENTRY(__bss_start)
-#if defined(CONFIG_FADS) || defined(CONFIG_ICU862)
+#if defined(CONFIG_ICU862)
GOT_ENTRY(environment)
#endif
END_GOT
* Now clear BSS segment
*/
lwz r3,GOT(__bss_start)
-#if defined(CONFIG_FADS) || defined(CONFIG_ICU862)
+#if defined(CONFIG_ICU862)
/*
* For the FADS - the environment is the very last item in flash.
* The real .bss stops just before environment starts, so only
--- /dev/null
+ LYNX KDI SUPPORT
+
+ Last Update: July 20, 2003
+=======================================================================
+
+This file describes support for LynuxWorks KDI within U-Boot. Support
+is enabled by defining CONFIG_LYNXKDI.
+
+
+LYNXOS AND BLUECAT SUPPORTED
+============================
+Both LynxOS and BlueCat linux KDIs are supported. The implementation
+automatically detects which is being booted. When you use mkimage
+you should specify "lynxos" for both (see target-specific notes).
+
+
+SUPPORTED ARCHITECTURE/TARGETS
+==============================
+The following targets have been tested:
+
+-PowerPC MPC8260ADS
+
+
+FILES TO LOOK AT
+================
+include/lynxkdi.h -defines a simple struct passed to a kdi.
+common/lynxkdi.c -implements the call to the kdi.
+common/cmd_bootm.c -top-level command implementation ("bootm").
+
+
+====================================================================
+TARGET SPECIFIC NOTES
+====================================================================
+
+MPC8260ADS
+===========
+The default LynxOS and BlueCat implementations require some
+modifications to the config file.
+
+Edit include/configs/MPC8260ADS.h to use the following:
+
+#define CFG_IMMR 0xFA200000
+#define CFG_BCSR 0xFA100000
+#define CFG_BR1_PRELIM 0xFA101801
+
+When creating a LynxOS or BlueCat u-boot image using mkimage,
+you must specify the following:
+
+Both: -A ppc -O lynxos -T kernel -C none
+LynxOS: -a 0x00004000 -e 0x00004020
+BlueCat: -a 0x00500000 -e 0x00507000
+
+To pass the MAC address to BlueCat you should define the
+"fcc2_ether_addr" parameter in the "bootargs" environment
+variable. E.g.:
+
+==> setenv bootargs fcc2_ether_addr=00:11:22:33:44:55:66
/* NAND */
#define CFG_NAND_BASE NAND_BASE
-
-#define CONFIG_MTD_NAND_ECC_JFFS2 1
+#define CONFIG_MTD_NAND_ECC_JFFS2
#define CFG_MAX_NAND_DEVICE 1
* Steven J. Hill <sjhill@cotw.com>
* Thomas Gleixner <gleixner@autronix.de>
*
- * $Id: nand.h,v 1.13 2002/04/28 13:40:41 gleixner Exp $
+ * $Id: nand.h,v 1.7 2003/07/24 23:30:46 a0384864 Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
#define NAND_NOOB_ECCPOS1 1
#define NAND_NOOB_ECCPOS2 2
#define NAND_NOOB_ECCPOS3 3
-#define NAND_NOOB_ECCPOS4 4
-#define NAND_NOOB_ECCPOS5 5
+#define NAND_NOOB_ECCPOS4 6
+#define NAND_NOOB_ECCPOS5 7
#define NAND_NOOB_BADBPOS -1
#define NAND_NOOB_ECCVPOS -1
--- /dev/null
+/*
+ * (C) Copyright 2003
+ * Orbacom Systems, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __LYNXKDI_H__
+#define __LYNXKDI_H__
+
+
+/* Boot parameter struct passed to kernel
+ */
+typedef struct lynxos_bootparms_t {
+ uint8_t rsvd1[2]; /* Reserved */
+ uint8_t ethaddr[6]; /* Ethernet address */
+ uint16_t flags; /* Boot flags */
+ uint32_t rate; /* System frequency */
+ uint32_t clock_ref; /* Time reference */
+ uint32_t dramsz; /* DRAM size */
+ uint32_t rsvd2; /* Reserved */
+} lynxos_bootparms_t;
+
+
+#endif /* __LYNXKDI_H__ */
* PLPRCR - PLL, Low-Power, and Reset Control Register 15-30
*/
#ifdef CONFIG_MPC866_et_al
-#define PLPRCR_MF_MSK 0xffff0000 /* Multiplication factor bits */
+#define PLPRCR_MF_MSK 0xffff001e /* Multiplication factor + PDF bits */
#define PLPRCR_MFN_MSK 0xf8000000 /* Multiplication factor numerator bits */
#define PLPRCR_MFN_SHIFT 0x0000001b /* Multiplication factor numerator shift*/
#define PLPRCR_MFD_MSK 0x03c00000 /* Multiplication factor denominator bits */
#define PLPRCR_MFD_SHIFT 0x00000017 /* Multiplication factor denominator shift*/
-#define PLPRCR_S_MSK 0x00300000 /* Multiplication factor integer bits */
-#define PLPRCR_S_SHIFT 0x00000014 /* Multiplication factor integer shift*/
-#define PLPRCR_MFI_MSK 0x000f0000 /* Multiplication factor integer bits */
-#define PLPRCR_MFI_SHIFT 0x00000010 /* Multiplication factor integer shift*/
+#define PLPRCR_S_MSK 0x00300000 /* Multiplication factor integer bits */
+#define PLPRCR_S_SHIFT 0x00000014 /* Multiplication factor integer shift */
+#define PLPRCR_MFI_MSK 0x000f0000 /* Multiplication factor integer bits */
+#define PLPRCR_MFI_SHIFT 0x00000010 /* Multiplication factor integer shift */
#else
#define PLPRCR_MF_MSK 0xfff00000 /* Multiplication factor bits */
#define PLPRCR_MF_SHIFT 0x00000014 /* Multiplication factor shift value */