Commit cbd8a35c authored by wdenk's avatar wdenk
Browse files

* Patch by Masami Komiy, 22 Feb 2004:

  Add support for NFS for file download

* Minor code cleanup
parent 074cff0d
......@@ -2,6 +2,9 @@
Changes for U-Boot 1.0.2:
======================================================================
* Patch by Masami Komiy, 22 Feb 2004:
Add support for NFS for file download
* Patch by Andrea Scian, 17 Feb 2004:
Add support for S3C44B0 processor and DAVE B2 board
......
......@@ -575,10 +575,10 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
kbd->bi_sccfreq /= 1000000L;
kbd->bi_vco /= 1000000L;
#endif /* CONFIG_8260 */
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
kbd->bi_ipbfreq /= 1000000L;
kbd->bi_pcifreq /= 1000000L;
#endif /* CONFIG_MPC5XXX */
#endif /* CONFIG_MPC5xxx */
}
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))hdr->ih_ep;
......
......@@ -32,6 +32,8 @@
#include <config.h>
#include <command.h>
#if (CONFIG_COMMANDS & CFG_CMD_ITEST)
#define EQ 0
#define NE 1
#define LT 2
......@@ -195,3 +197,4 @@ U_BOOT_CMD(
"itest - return true/false on integer compare\n",
"[.b, .w, .l, .s] [*]value1 <op> [*]value2\n"
);
#endif /* CONFIG_COMMANDS & CFG_CMD_ITEST */
......@@ -38,6 +38,7 @@
#if (CONFIG_COMMANDS & (CFG_CMD_MEMORY | \
CFG_CMD_I2C | \
CFG_CMD_ITEST | \
CFG_CMD_PCI | \
CMD_CMD_PORTIO ) )
int cmd_get_data_size(char* arg, int default_size)
......
......@@ -81,6 +81,19 @@ U_BOOT_CMD(
);
#endif /* CFG_CMD_DHCP */
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
int do_nfs (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
return netboot_common(NFS, cmdtp, argc, argv);
}
U_BOOT_CMD(
nfs, 3, 1, do_nfs,
"nfs - boot image via network using NFS protocol\n",
"[loadAddress] [host ip addr:bootfilename]\n"
);
#endif /* CFG_CMD_NFS */
static void netboot_update_env(void)
{
char tmp[16] ;
......
......@@ -23,5 +23,5 @@
PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi
PLATFORM_CPPFLAGS += -DCONFIG_MPC5XXX -ffixed-r2 -ffixed-r29 \
PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx -ffixed-r2 -ffixed-r29 \
-mstring -mcpu=603e -mmultiple
......@@ -183,7 +183,7 @@ int cpu_init_r (void)
/* route critical ints to normal ints */
*(vu_long *)MPC5XXX_ICTL_EXT |= 0x00000001;
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_MPC5XXX_FEC)
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_MPC5xxx_FEC)
/* load FEC microcode */
loadtask(0, 2);
#endif
......
......@@ -17,7 +17,7 @@
/* #define DEBUG 0x28 */
#if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
defined(CONFIG_MPC5XXX_FEC)
defined(CONFIG_MPC5xxx_FEC)
#if (DEBUG & 0x60)
static void tfifo_print(mpc5xxx_fec_priv *fec);
......@@ -980,4 +980,4 @@ static uint32 local_crc32(char *string, unsigned int crc_value, int len)
}
#endif /* DEBUG */
#endif /* CONFIG_MPC5XXX_FEC */
#endif /* CONFIG_MPC5xxx_FEC */
......@@ -29,7 +29,7 @@
#include <mpc5xxx.h>
#include <version.h>
#define CONFIG_MPC5XXX 1 /* needed for Linux kernel header files */
#define CONFIG_MPC5xxx 1 /* needed for Linux kernel header files */
#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
#include <ppc_asm.tmpl>
......
......@@ -46,7 +46,7 @@ typedef struct global_data {
unsigned long scc_clk;
unsigned long brg_clk;
#endif
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
unsigned long ipb_clk;
unsigned long pci_clk;
#endif
......
......@@ -42,7 +42,7 @@ typedef struct bd_info {
|| defined(CONFIG_E500)
unsigned long bi_immr_base; /* base of IMMR register */
#endif
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
unsigned long bi_mbar_base; /* base of internal registers */
#endif
unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */
......@@ -57,7 +57,7 @@ typedef struct bd_info {
unsigned long bi_sccfreq; /* SCC_CLK Freq, in MHz */
unsigned long bi_vco; /* VCO Out from PLL, in MHz */
#endif
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
unsigned long bi_ipbfreq; /* IPB Bus Freq, in MHz */
unsigned long bi_pcifreq; /* PCI Bus Freq, in MHz */
#endif
......
......@@ -18,7 +18,7 @@ unsigned short bmp_logo_palette[] = {
0x0343, 0x0454, 0x0565, 0x0565, 0x0676, 0x0787, 0x0898, 0x0999,
0x0AAA, 0x0ABA, 0x0BCB, 0x0CCC, 0x0DDD, 0x0EEE, 0x0FFF, 0x0FB3,
0x0FB4, 0x0FC4, 0x0FC5, 0x0FC6, 0x0FD7, 0x0FD8, 0x0FD9, 0x0FDA,
0x0FEA, 0x0FEB, 0x0FEC, 0x0FFD, 0x0FFE, 0x0FFF, 0x0FFF,
0x0FEA, 0x0FEB, 0x0FEC, 0x0FFD, 0x0FFE, 0x0FFF, 0x0FFF,
};
unsigned char bmp_logo_bitmap[] = {
......
......@@ -86,6 +86,7 @@
#define CFG_CMD_FAT 0x0010000000000000U /* FAT support */
#define CFG_CMD_IMLS 0x0020000000000000U /* List all found images */
#define CFG_CMD_ITEST 0x0040000000000000U /* Integer (and string) test */
#define CFG_CMD_NFS 0x0080000000000000U /* NFS support */
#define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFFU /* ALL commands */
......
......@@ -319,6 +319,7 @@ void relocate_code (ulong, gd_t *, ulong);
ulong get_endaddr (void);
void trap_init (ulong);
#if defined (CONFIG_4xx) || \
defined (CONFIG_5xxx) || \
defined (CONFIG_74xx_7xx) || \
defined (CONFIG_74x) || \
defined (CONFIG_75x) || \
......@@ -361,7 +362,7 @@ int sdram_adjust_866 (void);
#if defined(CONFIG_8260)
int prt_8260_clks (void);
#endif
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
int prt_mpc5xxx_clks (void);
#endif
#ifdef CONFIG_4xx
......
......@@ -29,7 +29,7 @@
* (easy to change)
*/
#define CONFIG_MPC5XXX 1 /* This is an MPC5xxx CPU */
#define CONFIG_MPC5xxx 1 /* This is an MPC5xxx CPU */
#define CONFIG_ICECUBE 1 /* ... on IceCube board */
#define CFG_MPC5XXX_CLKIN 33000000 /* ... running at 33.000000MHz */
......@@ -213,7 +213,7 @@
/*
* Ethernet configuration
*/
#define CONFIG_MPC5XXX_FEC 1
#define CONFIG_MPC5xxx_FEC 1
#define CONFIG_FEC_10MBIT 1 /* Workaround for FEC 100Mbit problem */
#define CONFIG_PHY_ADDR 0x00
......
......@@ -41,7 +41,7 @@
* (easy to change)
*/
#define CONFIG_MPC5XXX 1 /* This is an MPC5xxx CPU */
#define CONFIG_MPC5xxx 1 /* This is an MPC5xxx CPU */
#define CONFIG_MPC5200 1 /* More exactly a MPC5200 */
#define CONFIG_TOP5200 1 /* ... on TOP5200 board - we need this for FEC.C */
......@@ -281,7 +281,7 @@
/*
* Ethernet configuration
*/
#define CONFIG_MPC5XXX_FEC 1
#define CONFIG_MPC5xxx_FEC 1
#define CONFIG_FEC_10MBIT 1 /* Workaround for FEC 100Mbit problem */
#define CONFIG_PHY_ADDR 0x1f
#define CONFIG_PHY_TYPE 0x79c874
......
......@@ -21,13 +21,13 @@
# endif
#endif /* CONFIG_8xx */
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
# if !defined(CONFIG_NET_MULTI)
# if defined(CONFIG_MPC5XXX_FEC)
# if defined(CONFIG_MPC5xxx_FEC)
# define CONFIG_NET_MULTI
# endif
# endif
#endif /* CONFIG_MPC5XXX */
#endif /* CONFIG_MPC5xxx */
#if !defined(CONFIG_NET_MULTI) && (defined(CONFIG_8260) || defined(CONFIG_MPC8560))
#include <config.h>
......@@ -306,7 +306,7 @@ extern int NetState; /* Network loop state */
extern int NetRestartWrap; /* Tried all network devices */
#endif
typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS } proto_t;
typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS } proto_t;
/* from net/net.c */
extern char BootFile[128]; /* Boot File name */
......
......@@ -175,7 +175,7 @@
#define IM_IMMR (IM_REGBASE+0x01a8)
#define IM_SCCR (IM_REGBASE+0x0c80)
#elif defined(CONFIG_MPC5XXX)
#elif defined(CONFIG_MPC5xxx)
#define HID0_ICE_BITPOS 16
#define HID0_DCE_BITPOS 17
......
......@@ -32,7 +32,7 @@
#ifdef CONFIG_5xx
#include <mpc5xx.h>
#endif
#ifdef CONFIG_MPC5XXX
#ifdef CONFIG_MPC5xxx
#include <mpc5xxx.h>
#endif
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
......@@ -288,9 +288,9 @@ init_fnc_t *init_sequence[] = {
prt_8260_clks,
#endif /* CONFIG_8260 */
checkcpu,
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
prt_mpc5xxx_clks,
#endif /* CONFIG_MPC5XXX */
#endif /* CONFIG_MPC5xxx */
checkboard,
INIT_FUNC_WATCHDOG_INIT
#if defined(CONFIG_MISC_INIT_F)
......@@ -478,7 +478,7 @@ void board_init_f (ulong bootflag)
defined(CONFIG_E500)
bd->bi_immr_base = CFG_IMMR; /* base of IMMR register */
#endif
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
bd->bi_mbar_base = CFG_MBAR; /* base of internal registers */
#endif
......@@ -493,10 +493,10 @@ void board_init_f (ulong bootflag)
bd->bi_sccfreq = gd->scc_clk;
bd->bi_vco = gd->vco_out;
#endif /* CONFIG_8260 */
#if defined(CONFIG_MPC5XXX)
#if defined(CONFIG_MPC5xxx)
bd->bi_ipbfreq = gd->ipb_clk;
bd->bi_pcifreq = gd->pci_clk;
#endif /* CONFIG_MPC5XXX */
#endif /* CONFIG_MPC5xxx */
bd->bi_baudrate = gd->baudrate; /* Console Baudrate */
#ifdef CFG_EXTBDINFO
......
......@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
LIB = libnet.a
OBJS = net.o tftp.o bootp.o rarp.o eth.o
OBJS = net.o tftp.o bootp.o rarp.o eth.o nfs.o
all: $(LIB)
$(LIB): $(START) $(OBJS)
......
......@@ -155,7 +155,7 @@ int eth_initialize(bd_t *bis)
#if defined(FEC_ENET) || defined(CONFIG_ETHER_ON_FCC)
fec_initialize(bis);
#endif
#if defined(CONFIG_MPC5XXX_FEC)
#if defined(CONFIG_MPC5xxx_FEC)
mpc5xxx_fec_initialize(bis);
#endif
#if defined(CONFIG_SK98)
......
......@@ -55,6 +55,15 @@
* derived from our own IP address)
* We want: - load the boot file
* Next step: none
*
* NFS:
*
* Prerequisites: - own ethernet address
* - own IP address
* - name of bootfile (if unknown, we use a default name
* derived from our own IP address)
* We want: - load the boot file
* Next step: none
*/
......@@ -65,6 +74,7 @@
#include "bootp.h"
#include "tftp.h"
#include "rarp.h"
#include "nfs.h"
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#include <miiphy.h>
......@@ -278,6 +288,9 @@ restart:
*/
switch (protocol) {
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
#if (CONFIG_COMMANDS & CFG_CMD_PING)
case PING:
#endif
......@@ -287,6 +300,9 @@ restart:
NetOurSubnetMask= getenv_IPaddr ("netmask");
switch (protocol) {
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
case TFTP:
NetServerIP = getenv_IPaddr ("serverip");
break;
......@@ -356,6 +372,11 @@ restart:
case PING:
PingStart();
break;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
NfsStart();
break;
#endif
default:
break;
......@@ -918,6 +939,9 @@ static int net_check_prereq (proto_t protocol)
return (1);
}
goto common;
#endif
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
case TFTP:
if (NetServerIP == 0) {
......
/*
* NFS support driver - based on etherboot and U-BOOT's tftp.c
*
* Masami Komiya <mkomiya@sonare.it> 2004
*
*/
/* NOTE: the NFS code is heavily inspired by the NetBSD netboot code (read:
* large portions are copied verbatim) as distributed in OSKit 0.97. A few
* changes were necessary to adapt the code to Etherboot and to fix several
* inconsistencies. Also the RPC message preparation is done "by hand" to
* avoid adding netsprintf() which I find hard to understand and use. */
/* NOTE 2: Etherboot does not care about things beyond the kernel image, so
* it loads the kernel image off the boot server (ARP_SERVER) and does not
* access the client root disk (root-path in dhcpd.conf), which would use
* ARP_ROOTSERVER. The root disk is something the operating system we are
* about to load needs to use. This is different from the OSKit 0.97 logic. */
/* NOTE 3: Symlink handling introduced by Anselm M Hoffmeister, 2003-July-14
* If a symlink is encountered, it is followed as far as possible (recursion
* possible, maximum 16 steps). There is no clearing of ".."'s inside the
* path, so please DON'T DO THAT. thx. */
#include <common.h>
#include <command.h>
#include <net.h>
#include <malloc.h>
#include "nfs.h"
#include "bootp.h"
/*#define NFS_DEBUG*/
#if ((CONFIG_COMMANDS & CFG_CMD_NET) && (CONFIG_COMMANDS & CFG_CMD_NFS))
#define HASHES_PER_LINE 65 /* Number of "loading" hashes per line */
#define NFS_TIMEOUT 10
static int fs_mounted = 0;
static unsigned long rpc_id;
static int nfs_offset = -1;
static int nfs_len;
static char dirfh[NFS_FHSIZE]; /* file handle of directory */
static char filefh[NFS_FHSIZE]; /* file handle of kernel image */
static IPaddr_t NfsServerIP;
static int NfsSrvMountPort;
static int NfsSrvNfsPort;
static int NfsOurPort;
static int NfsTimeoutCount;
static int NfsState;
#define STATE_PRCLOOKUP_PROG_MOUNT_REQ 1
#define STATE_PRCLOOKUP_PROG_NFS_REQ 2
#define STATE_MOUNT_REQ 3
#define STATE_UMOUNT_REQ 4
#define STATE_LOOKUP_REQ 5
#define STATE_READ_REQ 6
#define STATE_READLINK_REQ 7
static char default_filename[64];
static char *nfs_filename;
static char *nfs_path;
static char nfs_path_buff[2048];
static __inline__ void
store_block (uchar * src, unsigned offset, unsigned len)
{
#ifdef CFG_DIRECT_FLASH_NFS
int i, rc = 0;
for (i=0; i<CFG_MAX_FLASH_BANKS; i++) {
/* start address in flash? */
if (load_addr + offset >= flash_info[i].start[0]) {
rc = 1;
break;
}
}
if (rc) { /* Flash is destination for this packet */
rc = flash_write ((uchar *)src, (ulong)(load_addr+offset), len);
if (rc) {
flash_perror (rc);
NetState = NETLOOP_FAIL;
return;
}
} else
#endif /* CFG_DIRECT_FLASH_NFS */
{
(void)memcpy ((void *)(load_addr + offset), src, len);
}
}
static char*
basename (char *path)
{
char *fname;
fname = path + strlen(path) - 1;
while (fname >= path) {
if (*fname == '/') {
fname++;
break;
}
fname--;
}
return fname;
}
static char*
dirname (char *path)
{
char *fname;
fname = basename (path);
--fname;
*fname = '\0';
return path;
}
/**************************************************************************
RPC_INIT - set up the ID counter to something fairly random
**************************************************************************/
static void
rpc_init (void)
{
unsigned long t;
t=get_ticks();
rpc_id = t ^ (t << 8) ^ (t << 16);
}
/**************************************************************************
RPC_ADD_CREDENTIALS - Add RPC authentication/verifier entries
**************************************************************************/
static long *rpc_add_credentials (long *p)
{
int hl;
int hostnamelen;
char hostname[256];
strcpy (hostname, "");
hostnamelen=strlen (hostname);
/* Here's the executive summary on authentication requirements of the
* various NFS server implementations: Linux accepts both AUTH_NONE
* and AUTH_UNIX authentication (also accepts an empty hostname field
* in the AUTH_UNIX scheme). *BSD refuses AUTH_NONE, but accepts
* AUTH_UNIX (also accepts an empty hostname field in the AUTH_UNIX
* scheme). To be safe, use AUTH_UNIX and pass the hostname if we have
* it (if the BOOTP/DHCP reply didn't give one, just use an empty
* hostname). */
hl = (hostnamelen + 3) & ~3;
/* Provide an AUTH_UNIX credential. */
*p++ = htonl(1); /* AUTH_UNIX */
*p++ = htonl(hl+20); /* auth length */
*p++ = htonl(0); /* stamp */
*p++ = htonl(hostnamelen); /* hostname string */
if (hostnamelen & 3) {
*(p + hostnamelen / 4) = 0; /* add zero padding */
}
memcpy (p, hostname, hostnamelen);
p += hl / 4;
*p++ = 0; /* uid */
*p++ = 0; /* gid */
*p++ = 0; /* auxiliary gid list */
/* Provide an AUTH_NONE verifier. */
*p++ = 0; /* AUTH_NONE */
*p++ = 0; /* auth length */
return p;
}
/**************************************************************************
RPC_LOOKUP - Lookup RPC Port numbers
**************************************************************************/
static void
rpc_req (int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
{
struct rpc_t pkt;
unsigned long id;
uint32_t *p;
int pktlen;
int sport;
id = rpc_id++;
pkt.u.call.id = htonl(id);
pkt.u.call.type = htonl(MSG_CALL);
pkt.u.call.rpcvers = htonl(2); /* use RPC version 2 */
pkt.u.call.prog = htonl(rpc_prog);
pkt.u.call.vers = htonl(2); /* portmapper is version 2 */
pkt.u.call.proc = htonl(rpc_proc);
p = (uint32_t *)&(pkt.u.call.data);
if (datalen)
memcpy ((char *)p, (char *)data, datalen*sizeof(uint32_t));
pktlen = (char *)p + datalen*sizeof(uint32_t) - (char *)&pkt;
memcpy ((char *)NetTxPacket+ETHER_HDR_SIZE+IP_HDR_SIZE, (char *)&pkt, pktlen);
if (rpc_prog == PROG_PORTMAP)
sport = SUNRPC_PORT;
else if (rpc_prog == PROG_MOUNT)
sport = NfsSrvMountPort;
else
sport = NfsSrvNfsPort;
NetSendUDPPacket (NetServerEther, NfsServerIP, sport, NfsOurPort, pktlen);
}
/**************************************************************************
RPC_LOOKUP - Lookup RPC Port numbers
**************************************************************************/
static void
rpc_lookup_req (int prog, int ver)
{
uint32_t data[16];
data[0] = 0; data[1] = 0; /* auth credential */
data[2] = 0; data[3] = 0; /* auth verifier */
data[4] = htonl(prog);
data[5] = htonl(ver);
data[6] = htonl(17); /* IP_UDP */
data[7] = 0;
rpc_req (PROG_PORTMAP, PORTMAP_GETPORT, data, 8);
}
/**************************************************************************
NFS_MOUNT - Mount an NFS Filesystem
**************************************************************************/
static void
nfs_mount_req (char *path)
{
uint32_t data[1024];
uint32_t *p;
int len;
int pathlen;
pathlen = strlen (path);
p = &(data[0]);
p = (uint32_t *)rpc_add_credentials((long *)p);
*p++ = htonl(pathlen);
if (pathlen & 3) *(p + pathlen / 4) = 0;
memcpy (p, path, pathlen);
p += (pathlen + 3) / 4;
len = (uint32_t *)p - (uint32_t *)&(data[0]);
rpc_req (PROG_MOUNT, MOUNT_ADDENTRY, data, len);
}
/**************************************************************************
NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
**************************************************************************/
static void
nfs_umountall_req (void)