- Network Interface configuration using environment variables or RARP or BOOTP
- image download and booting over Ethernet using TFTP
- automatic booting over ethernet when "autostart=yes" and
downloaded image is bootable
* Some code cleanup to make easier adaptable to different hardware
* Bug fixes, especially:
- avoid clobbering the PLL divider in interrupts.c (thanks to Till Straumann)
- make Ethernet code work on SCC1 or SCC2
+======================================================================
+Open Issues:
+======================================================================
+
* ppc/vsprintf.c:
Eliminate asc_to_hex() - replace by simple_strtoul()
Fix Exception handling for "Software Emulation Exception" etc.
+======================================================================
+Modifications for 0.4.4:
+======================================================================
+
+* Added Network support; allows:
+
+ - Network Interface configuration using environment variables or
+ RARP or BOOTP
+ - image download and booting over Ethernet using TFTP
+ - automatic booting over ethernet when "autostart=yes" and
+ downloaded image is bootable
+
+* Some code cleanup to make easier adaptable to different hardware
+
+* Bug fixes, especially:
+
+ - avoid clobbering the PLL divider in interrupts.c (thanks to Till
+ Straumann)
+ - make Ethernet code work on SCC1 or SCC2
+
======================================================================
Modifications for 0.4.4-pre2:
======================================================================
#include <cmd_net.h>
#include <net.h>
+static void netboot_common (int, cmd_tbl_t *, bd_t *, int , char *[]);
-void do_net (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+
+void do_bootp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
{
- ulong addr, i;
+ netboot_common (BOOTP, cmdtp, bd, argc, argv);
+}
- printf ("bootnet called with %d args:\n", argc);
- for (i=0; i<argc; i++)
- printf ("%s\n", argv[i]);
+void do_tftpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ netboot_common (TFTP, cmdtp, bd, argc, argv);
+}
-if (argc == 1) {
-#ifdef CONFIG_8xx
- NetLoop(bd, "", -1);
-#else
- printf ("Network Support not implemented yet on this architecture\n");
-#endif
+void do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ netboot_common (RARP, cmdtp, bd, argc, argv);
}
-else if (argc == 2) {
-#if 0
- switch (*argv[1]) {
- case 'i': immr->pio.pcpar &= ~(0x0008);
- printf("switched to internal loop\n");
- break;
- case 'e':immr->pio.pcpar |= (0x0008);
- printf("switched to external loop\n");
+
+static void
+netboot_common (int proto, cmd_tbl_t *cmdtp, bd_t *bd, int argc, char *argv[])
+{
+#ifdef CONFIG_8xx
+ ulong addr;
+ int rc;
+ char *s;
+ extern ulong TftpLoadAddress;
+
+ switch (argc) {
+ case 1: rc = NetLoop(bd, BOOTP, "", -1);
break;
- case 's': printf ("bus: %ld cpu: %ld ip: %ld\n", bd->bi_busfreq, bd->bi_intfreq, bd->bi_ip_addr);
+ case 2: asc_to_hex(argv[1], &addr);
+ rc = NetLoop(bd, BOOTP, "", addr);
break;
-/* case 'r': tftp_recv("netti", loadBuf, 0);
+ case 3: asc_to_hex(argv[1], &addr);
+ rc = NetLoop(bd, BOOTP, argv[2], addr);
break;
-*/ }
-#endif
-#ifdef CONFIG_8xx
- NetLoop(bd, argv[1], -1);
-#else
- printf ("Network Support not implemented yet on this architecture\n");
-#endif
+ default: printf ("Usage:\n%s\n", cmdtp->usage);
+ return;
+ }
+
+ if (rc == 0)
+ return;
+
+ /* Loading ok, check if we should attempt an auto-start */
+ if (((s = getenv("autostart")) != NULL) && (strcmp(s,"yes") == 0)) {
+ char *local_args[3];
+ char local_str[32];
+ sprintf (local_str, "%lX", TftpLoadAddress);
+ local_args[0] = argv[0];
+ local_args[1] = local_str;
+ local_args[2] = NULL;
+
+ printf ("Automatic boot of image at addr 0x%08lX ...\n",
+ TftpLoadAddress);
+
+ do_bootm (cmdtp, bd, 0, 2, local_args);
+ }
-}
-else if (argc == 3) {
- asc_to_hex(argv[2], &addr);
-#ifdef CONFIG_8xx
- NetLoop(bd, argv[1], addr);
#else
printf ("Network Support not implemented yet on this architecture\n");
#endif
}
-
-}
cmd_tbl_t cmd_tbl[] = {
CMD_TBL_GO,
CMD_TBL_BOOTM,
- CMD_TBL_NET,
+ CMD_TBL_BOOTP,
+ CMD_TBL_TFTPB,
+ CMD_TBL_RARPB,
CMD_TBL_LOADS,
CMD_TBL_MD,
CMD_TBL_MM,
.ascii "baudrate="
.ascii MK_STR(CONFIG_BAUDRATE)
.ascii "\0"
- .ascii "\0"
.ascii "loads_echo="
.ascii MK_STR(CONFIG_LOADS_ECHO)
.ascii "\0"
+ /* terminate list of environment strings */
+ .ascii "\0"
. = environment + CFG_FLASH_ENV_SIZE
.L_end:
#if defined(CONFIG_FADS)
case FLASH_MAN_AMD: printf ("AMD "); break;
case FLASH_MAN_FUJ: printf ("FUJITSU "); break;
case FLASH_MAN_SST: printf ("SST "); break;
+ case FLASH_MAN_STM: printf ("STM "); break;
default: printf ("Unknown Vendor "); break;
}
break;
case FLASH_SST400A: printf ("39xF400A (4M = 256K x 16)\n");
break;
- case FLASH_SST800A: printf ("39xF400A (8M = 512K x 16)\n");
+ case FLASH_SST800A: printf ("39xF800A (8M = 512K x 16)\n");
+ break;
+ case FLASH_STM800AB: printf ("M29W800AB (8M = 512K x 16)\n");
break;
default: printf ("Unknown Chip Type\n");
break;
case SST_MANUFACT:
info->flash_id = FLASH_MAN_SST;
break;
+ case STM_MANUFACT:
+ info->flash_id = FLASH_MAN_STM;
+ break;
default:
info->flash_id = FLASH_UNKNOWN;
info->sector_count = 0;
info->flash_id += FLASH_SST800A;
info->sector_count = 256; /* 39xF800A ID ( 8M = 512K x 16 ) */
info->size = 0x00200000;
- break;
+ break; /* => 2 MB */
+ case STM_ID_x800AB:
+ info->flash_id += FLASH_STM800AB;
+ info->sector_count = 19;
+ info->size = 0x00200000;
+ break; /* => 2 MB */
default:
info->flash_id = FLASH_UNKNOWN;
return (0); /* => no or unknown flash */
void do_bootm (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
#define CMD_TBL_BOOTM MK_CMD_TBL_ENTRY( \
- "bootm", 3, CFG_MAXARGS, do_bootm, \
+ "bootm", 5, CFG_MAXARGS, do_bootm, \
"bootm - boot application image from memory\n", \
"addr [arg ...]\n - boot application image stored in memory\n" \
" passing arguments 'arg ...'; when booting a Linux kernel,\n" \
*/
/*
- * Boot support
+ * Network boot support
*/
#ifndef _CMD_NET_H
#define _CMD_NET_H
-#define CMD_TBL_NET MK_CMD_TBL_ENTRY( \
- "net", 3, 3, do_net, \
- "net - boot image via network\n", \
- "[bootfilename] [loadAddress]\n" \
+#define CMD_TBL_BOOTP MK_CMD_TBL_ENTRY( \
+ "bootp", 5, 3, do_bootp, \
+ "bootp - boot image via network using BootP/TFTP protocol\n", \
+ "[loadAddress] [bootfilename]\n" \
)
-void do_net (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+void do_bootp (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+#define CMD_TBL_TFTPB MK_CMD_TBL_ENTRY( \
+ "tftpboot", 4, 3, do_tftpb, \
+ "tftpboot- boot image via network using TFTP protocol\n" \
+ " and env variables ipaddr and serverip\n", \
+ "[loadAddress] [bootfilename]\n" \
+)
+
+
+void do_tftpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+
+#define CMD_TBL_RARPB MK_CMD_TBL_ENTRY( \
+ "rarpboot", 4, 3, do_rarpb, \
+ "rarpboot- boot image via network using RARP/TFTP protocol\n", \
+ "[loadAddress] [bootfilename]\n" \
+)
+
+
+void do_rarpb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
#endif
* Note TENA is on Port B.
*/
#define PROFF_ENET PROFF_SCC2
+#define CPM_CR_ENET CPM_CR_CH_SCC2
#define SCC_ENET 1
#define PA_ENET_RXD ((ushort)0x0004)
#define PA_ENET_TXD ((ushort)0x0008)
* Note TENA is on Port B.
*/
#define PROFF_ENET PROFF_SCC2
+#define CPM_CR_ENET CPM_CR_CH_SCC2
#define SCC_ENET 1
#define PA_ENET_RXD ((ushort)0x0004)
#define PA_ENET_TXD ((ushort)0x0008)
* This is unique to the BSE ip-Engine board.
*/
#define PROFF_ENET PROFF_SCC2
+#define CPM_CR_ENET CPM_CR_CH_SCC2
#define SCC_ENET 1
#define PA_ENET_RXD ((ushort)0x0004)
#define PA_ENET_TXD ((ushort)0x0008)
* to configure the pins for SCC1 use.
*/
#define PROFF_ENET PROFF_SCC1
+#define CPM_CR_ENET CPM_CR_CH_SCC1
#define SCC_ENET 0
#define PA_ENET_RXD ((ushort)0x0001)
#define PA_ENET_TXD ((ushort)0x0002)
* to configure the pins for SCC2 use.
*/
#define PROFF_ENET PROFF_SCC2
+#define CPM_CR_ENET CPM_CR_CH_SCC2
#define SCC_ENET 1
#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
* to configure the pins for SCC1 use.
*/
#define PROFF_ENET PROFF_SCC2
+#define CPM_CR_ENET CPM_CR_CH_SCC2
#define SCC_ENET 1
#define PA_ENET_RXD ((ushort)0x0004) /* PA 13 */
#define PA_ENET_TXD ((ushort)0x0008) /* PA 12 */
* to configure the pins for SCC1 use.
*/
#define PROFF_ENET PROFF_SCC1
+#define CPM_CR_ENET CPM_CR_CH_SCC1
#define SCC_ENET 0
#define PA_ENET_RXD ((ushort)0x0001) /* PA 15 */
#define PA_ENET_TXD ((ushort)0x0002) /* PA 14 */
#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */
#define CFG_FLASH_ENV_OFFSET 0x8000 /* Offset of Environment Sector */
-#define CFG_FLASH_ENV_SIZE 0x2000 /* Total Size of Environment Sector */
+#define CFG_FLASH_ENV_SIZE 0x4000 /* Total Size of Environment Sector */
/*-----------------------------------------------------------------------
* Cache Configuration
*/
#define AMD_MANUFACT 0x00010001 /* AMD manuf. ID in D23..D16, D7..D0 */
#define FUJ_MANUFACT 0x00040004 /* FUJITSU manuf. ID in D23..D16, D7..D0 */
+#define STM_MANUFACT 0x00200020 /* STM (Thomson) manuf. ID in D23.. -"- */
#define SST_MANUFACT 0x00BF00BF /* SST manuf. ID in D23..D16, D7..D0 */
#define AMD_ID_F040B 0xA4 /* 29F040B ID ( 4 M, bottom boot sect) */
#define SST_ID_xF400A 0x27802780 /* 39xF400A ID ( 4M = 256K x 16 ) */
#define SST_ID_xF800A 0x27812781 /* 39xF800A ID ( 8M = 512K x 16 ) */
+#define STM_ID_x800AB 0x005B005B /* M29W800AB ID (8M = 512K x 16 ) */
+
/*-----------------------------------------------------------------------
* Internal FLASH identification codes
*/
#define FLASH_SST400A 0x0B /* SST 39xF400A ID ( 4M = 256K x 16 ) */
#define FLASH_SST800A 0x0C /* SST 39xF800A ID ( 8M = 512K x 16 ) */
+#define FLASH_STM800AB 0x0F /* STM M29WF800AB ID ( 8M = 512K x 16 ) */
+
#define FLASH_UNKNOWN 0xFF /* unknown flash type */
#define FLASH_MAN_AMD 0x00 /* manufacturer offsets */
#define FLASH_MAN_FUJ 0x10
#define FLASH_MAN_SST 0x20
+#define FLASH_MAN_STM 0x40
#define FLASH_TYPEMASK 0x0F /* extract FLASH type information */
#define FLASH_VENDMASK 0xF0 /* extract FLASH vendor information */
-#define FLASH_AMD_COMP 0x2F /* Up to this ID, FLASH is compatible */
+#define FLASH_AMD_COMP 0x4F /* Up to this ID, FLASH is compatible */
/* with AMD, Fujitsu and SST */
/* (JEDEC standard commands ?) */
*
* Copyright 1994 - 2000 Neil Russell.
* (See License)
+ *
+ *
+ * History
+ * 9/16/00 bor adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
*/
#ifndef __NET_H__
#define __NET_H__
-#ifndef __LIMON_H__
-/* #include "limon.h" */
-#endif /* __LIMON_H__ */
-
-
-/**** from cpu_target.h ******
- *
- * Address of the loader staging area. All downloaded images are
- * loaded here before being moved to their final destinations.
- */
-#define LOAD_ADDRESS 0x400000
/*
* The number of receive packet buffers, and the required packet buffer
#define PKTBUFSRX 4
#define PKTALIGN 32
-#ifndef ASS
-extern ulong MemSize;
-#endif
-
-/****** end from cpu_target.h ******/
-
/****** from cpu_arch.h ************/
/* Byte swapping stuff (not needed on PPC). */
/****** end from cpu_arch.h **************/
-/****** from limon.h **************/
-
-/* Timer stuff. */
-
-#define HZ 100
-
-/****** end from limon.h **********/
-
-
typedef ulong IPaddr_t;
-/**********************************************************************/
-/*
- * Ethernet card control structure
- */
+
/*
* The current receive packet handler. Called with a pointer to the
*/
typedef void thand_f(void);
-#if 0
-/*
- * Network loop start function.
- */
-typedef void start_f(void);
-
-/*
- * Ethernet card functions.
- */
-typedef int init_f(bd_t *bis);
-typedef void send_f(volatile uchar *, int);
-typedef void rx_f(void);
-typedef void halt_f(void);
-
-typedef struct
-{
- init_f * eth_init; /* Initialize the device */
- send_f * eth_send; /* Send a packet */
- rx_f * check_rx; /* Check for received packets */
- halt_f * eth_halt; /* Shutdown card */
-}
- NetCard_t;
-extern NetCard_t * NetCard; /* The card we found */
-
-extern NetCard_t SCCEthernet0;
-#endif
-
-extern int eth_init(bd_t *bis); /* Initialize the device */
-extern int eth_send(volatile void *packet, int length); /* Send a packet */
-extern int eth_rx(void); /* Check for received packets */
-extern void eth_halt(void); /* Shutdown card */
+extern int eth_init(bd_t *bis); /* Initialize the device */
+extern int eth_send(volatile void *packet, int length); /* Send a packet */
+extern int eth_rx(void); /* Check for received packets */
+extern void eth_halt(void); /* stop SCC */
#define E802_HDR_SIZE 22 /* 802 ethernet header size */
#define PROT_IP 0x0800 /* IP protocol */
#define PROT_ARP 0x0806 /* IP ARP protocol */
+#define PROT_RARP 0x8035 /* IP ARP protocol */
/*
* Internet Protocol (IP) header.
ushort ar_op; /* Operation */
# define ARPOP_REQUEST 1 /* Request to resolve address */
# define ARPOP_REPLY 2 /* Response to previous request */
+
+# define RARPOP_REQUEST 3 /* Request to resolve address */
+# define RARPOP_REPLY 4 /* Response to previous request */
+
/*
* The remaining fields are variable in size,
* according to the sizes above, and are defined
/* net.c */
extern uchar NetOurEther[6]; /* Our ethernet address */
extern uchar NetServerEther[6]; /* Boot server enet address */
-extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */
+extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */
extern IPaddr_t NetServerIP; /* Server IP addr (0 = unkn) */
-extern volatile uchar * NetTxPacket; /* THE transmit packet */
+extern volatile uchar * NetTxPacket; /* THE transmit packet */
extern volatile uchar * NetRxPackets[PKTBUFSRX]; /* Receive packets */
extern volatile uchar * NetRxPkt; /* Current receive packet */
extern int NetRxPktLen; /* Current rx packet length */
-extern unsigned NetIPID; /* IP ID (counting) */
+extern unsigned NetIPID; /* IP ID (counting) */
extern uchar NetBcastAddr[6]; /* Ethernet boardcast address */
extern int NetState; /* Network loop state */
#define NETLOOP_SUCCESS 3
#define NETLOOP_FAIL 4
+
+typedef enum { BOOTP, TFTP, RARP } proto_t;
+
/* Initialize the network adapter */
-extern int NetLoop(bd_t *bis, char *fileName, ulong loadAdr);
+extern int NetLoop(bd_t *bis, proto_t protocol, char *fileName, ulong loadAdr);
/* Shutdown adapters and cleanup */
extern void NetStop(void);
/**********************************************************************/
+/*
+ * Timer stuff.
+ */
+
+#define HZ 1
+
+/*
+ * Return the number of HZ ticks since we started.
+ */
+extern ulong GetTicksSinceBoot(void);
+
+
+
#endif /* __NET_H__ */
/* ppc/crc32.c */
ulong crc32 (ulong, const unsigned char *, uint);
-/* net/net.c */
-int NetLoop (bd_t *, char *, ulong);
-
#endif /* _PPCBOOT_H_ */
#ifndef __VERSION_H__
#define __VERSION_H__
-#define PPCBOOT_VERSION "ppcboot 0.4.4-pre2"
+#define PPCBOOT_VERSION "ppcboot 0.4.4"
#endif /* __VERSION_H__ */
*/
/* perform BR0 reset that MPC850 Rev. A can't guarantee */
- memctl->memc_br0 |= 0x00000001; /* just "bank valid" bit */
+ memctl->memc_br0 = 0x00000001; /* just "bank valid" bit */
/* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
* addresses - these have to be modified later when FLASH size
#include "commproc.h"
#include "net.h"
-#define TRUE 1
-#define FALSE 0
-
-#define ON 1
-#define OFF 0
-
-#if 0
-/* MAC Address */
-#define ETH_PHYS_ADDR_H (0x0008) /* Phys. Address (MSB) */
-#define ETH_PHYS_ADDR_M (0x5022) /* Phys. Address */
-#define ETH_PHYS_ADDR_L (0x6370) /* Phys. Address (LSB) */
-#endif
-
-#define BD_OFFSET 0x820 /* offset to begin of DPRAM + allocation for serial IF*/
+#define BD_OFFSET 0x860 /* offset to begin of DPRAM + allocation for serial IF*/
/* Ethernet Transmit and Receive Buffers */
#define DBUF_LENGTH 1520
-/* #define PKTBUFSRX 2 */
+
#define TX_BUF_CNT 2
+#define TOUT_LOOP 1000000
+
/* static char rxbuf[PKTBUFSRX][ DBUF_LENGTH ]; */
static char txbuf[TX_BUF_CNT][ DBUF_LENGTH ];
if (txIdx >= TX_BUF_CNT) txIdx = 0;
#endif
- while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<1000000)) j++;
- if (j>=1000000) printf("TX not ready\n");
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) j++;
+ if (j>=TOUT_LOOP) printf("TX not ready\n");
rtx->txbd[txIdx].cbd_bufaddr = (uint)packet;
rtx->txbd[txIdx].cbd_datlen = length;
rtx->txbd[txIdx].cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_LAST |BD_ENET_TX_WRAP);
- while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<1000000)) j++;
- if (j>=1000000) printf("TX timeout\n");
+ while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j<TOUT_LOOP)) j++;
+ if (j>=TOUT_LOOP) printf("TX timeout\n");
#ifdef ET_DEBUG
printf("cycles: %d status: %x\n", j, rtx->txbd[txIdx].cbd_sc);
#endif
/**************************************************************
*
- * SCC2 Ethernet Initialization Routine
+ * SCC Ethernet Initialization Routine
*
*************************************************************/
txIdx = 0;
/* assign static pointer to BD area */
- rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + 0x860 /* BD_OFFSET) */ );
+ rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + BD_OFFSET);
/* Configure port A pins for Txd and Rxd.
* Setup SCC Ethernet Parameter RAM
*/
- pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Normal Operation and Mot byte ordering */
- pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Normal access */
+ pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Normal Operation and Mot byte ordering */
+ pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Normal access */
- pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. ET package len 1520 */
+ pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. ET package len 1520 */
pram_ptr->sen_genscc.scc_rbase = (unsigned int)(&rtx->rxbd[0]); /* Set RXBD tbl start at Dual Port */
pram_ptr->sen_genscc.scc_tbase = (unsigned int)(&rtx->txbd[0]); /* Set TXBD tbl start at Dual Port */
pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */
#define ea bis->bi_enetaddr
-#if 0
- pram_ptr->sen_paddrh = (ea[1] << 8) + ea[0];
- pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
- pram_ptr->sen_paddrl = (ea[5] << 8) + ea[4];
-#endif
pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */
/*
- * Enter Command: Initialize Rx and Tx Params for SCC2
+ * Enter Command: Initialize Rx and Tx Params for SCC
*/
- while( immr->im_cpm.cp_cpcr & CPM_CR_FLG ){} /* SPIN UNTIL READY TO ISSUE COMMAND */
+ while( immr->im_cpm.cp_cpcr & CPM_CR_FLG ){} /* SPIN UNTIL READY TO ISSUE COMMAND */
/* ISSUE COMMAND */
- immr->im_cpm.cp_cpcr = ((CPM_CR_INIT_TRX << 8) | (CPM_CR_CH_SCC2 << 4) | CPM_CR_FLG);
- while( immr->im_cpm.cp_cpcr & CPM_CR_FLG ){} /* SPIN UNTIL COMMAND PROCESSED */
+ immr->im_cpm.cp_cpcr = ((CPM_CR_INIT_TRX << 8) | (CPM_CR_ENET << 4) | CPM_CR_FLG);
+ while( immr->im_cpm.cp_cpcr & CPM_CR_FLG ){} /* SPIN UNTIL COMMAND PROCESSED */
/*
* Clear Events in SCCE -- Clear bits by writing 1's
* Configure Ethernet TENA Signal
*/
-#if (defined(CONFIG_MBX) || defined(CONFIG_TQM860) || \
- defined(CONFIG_TQM860L) || defined(CONFIG_FPS850) )
+#if (defined(PC_ENET_TENA) && !defined(PB_ENET_TENA))
immr->im_ioport.iop_pcpar |= PC_ENET_TENA;
immr->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
-#endif
-
-#if (defined(CONFIG_TQM823L) || defined(CONFIG_TQM850L) || \
- defined(CONFIG_TQM855L) || defined(CONFIG_MPC850SAR))
+#elif (defined(PB_ENET_TENA) && !defined(PC_ENET_TENA))
immr->im_cpm.cp_pbpar |= PB_ENET_TENA;
immr->im_cpm.cp_pbdir |= PB_ENET_TENA;
+#else
+#error Configuration Error: exactly ONE of PB_ENET_TENA, PC_ENET_TENA must be defined
#endif
/*
NAME = $(shell basename $(DIR))
LIB = lib$(NAME).a
-OBJS = net.o tftp.o bootp.o
+OBJS = net.o tftp.o bootp.o rarp.o
all: $(LIB)
$(LIB): $(START) $(OBJS)
* (See License)
*/
-/* #include "limon.h" */
#include "ppcboot.h"
#include "net.h"
#include "bootp.h"
#include "tftp.h"
-#define TIMEOUT 15 /* Seconds before trying BOOTP again */
+#define TIMEOUT 5 /* Seconds before trying BOOTP again */
#define PORT_BOOTPS 67 /* BOOTP server UDP port */
#define PORT_BOOTPC 68 /* BOOTP client UDP port */
lAddr = loadAdr;
- printf("BOOTP broadcast %d\t", ++BootpTry);
+ printf("BOOTP broadcast %d\n", ++BootpTry);
pkt = NetTxPacket;
NetSetEther(pkt, NetBcastAddr, PROT_IP);
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
bp->bp_hops = 0;
- bp->bp_secs = SWAP16(/* GetTicksSinceBoot() */ 10000 / HZ);
+ bp->bp_secs = SWAP16( GetTicksSinceBoot() / HZ);
bp->bp_ciaddr = 0;
bp->bp_yiaddr = 0;
bp->bp_siaddr = 0;
NetCopyEther(bp->bp_chaddr, NetOurEther);
strcpy(bp->bp_file, fileName);
+ /* store boot file name for repetitions in case of bootp timeout */
+ strcpy(BootFile, fileName);
+
/*
* Bootp ID is the lower 4 bytes of our ethernet address
* plus the current time in HZ.
| ((ulong)NetOurEther[3] << 16)
| ((ulong)NetOurEther[4] << 8)
| (ulong)NetOurEther[5];
- BootpID += /* GetTicksSinceBoot() */ 1000;
+ BootpID += GetTicksSinceBoot();
bp->bp_id = BootpID;
NetSendPacket(NetTxPacket, BOOTP_SIZE);
/* bootp.c */
extern ulong BootpID; /* ID of cur BOOTP request */
extern char BootFile[128]; /* Boot file name */
+extern int BootpTry;
extern void BootpRequest(char *fileName, ulong loadAdr); /* Send a BOOTP request */
*
* Copyright 1994 - 2000 Neil Russell.
* (See License)
+ *
+ * History
+ * 9/16/00 bor adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
*/
-/*#include "limon.h" */
#include "ppcboot.h"
#include "net.h"
#include "bootp.h"
#include "tftp.h"
-
-typedef struct et_addr_s
-{
- union{
- unsigned char by[6];
- unsigned short sh[3];
- struct
- {
- unsigned char b0;
- unsigned char b1;
- unsigned char b2;
- unsigned char b3;
- unsigned char b4;
- unsigned char b5;
- }s;
- }u;
-}et_addr_t;
-
-typedef struct et_mac_addr_s
-{
- et_addr_t dst;
- et_addr_t src;
- unsigned short type;
-} et_mac_addr_t;
-
-#define ET_MAC_TYPE_IP 0x0800
-#define ET_MAC_TYPE_ARP 0x0806
-#define ET_MAC_TYPE_RARP 0x8035
-
-
+#include "rarp.h"
uchar NetOurEther[6]; /* Our ethernet address */
uchar NetServerEther[6]; /* Boot server enet address */
IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */
IPaddr_t NetServerIP; /* Our IP addr (0 = unknown) */
-volatile uchar * NetRxPkt; /* Current receive packet */
+volatile uchar * NetRxPkt; /* Current receive packet */
int NetRxPktLen; /* Current rx packet length */
unsigned NetIPID; /* IP packet ID */
uchar NetBcastAddr[6] = /* Ethernet bcast address */
static rxhand_f * packetHandler; /* Current RX packet handler */
static thand_f * timeHandler; /* Current timeout handler */
static ulong timeValue; /* Current timeout value */
-volatile uchar * NetTxPacket = 0; /* THE transmit packet */
-
-
-
-void display_mac_address (et_addr_t * et)
-{
- printf ("%x:%x:%x:%x:%x:%x\r\n", (et->u.sh[0] / 0x100),
- (et->u.sh[0] % 0x100),
- (et->u.sh[1] / 0x100),
- (et->u.sh[1] % 0x100),
- (et->u.sh[2] / 0x100),
- (et->u.sh[2] % 0x100));
-}
-
-void et_dump (et_mac_addr_t * mac_ptr)
-{
- char *tStr;
- printf ("\r\n **** ET Dump ****\r\nDestination :- ");
- display_mac_address (&(mac_ptr->dst));
- printf ("\r\nSource :- ");
- display_mac_address (&(mac_ptr->src));
- switch (mac_ptr->type) {
- case ET_MAC_TYPE_ARP : tStr="ARP"; break;
- case ET_MAC_TYPE_RARP: tStr="RARP"; break;
- case ET_MAC_TYPE_IP : tStr="IP" ; break;
- default: tStr="unknown" ; break;
- }
- printf ("\r\nType :- %s\n", tStr);
-}
+volatile uchar * NetTxPacket = 0; /* THE transmit packet */
+static ulong tb_factor;
/**********************************************************************/
*/
int
-NetLoop(bd_t *bis, char *fileName, ulong loadAdr)
+NetLoop(bd_t *bis, proto_t protocol, char *fileName, ulong loadAdr)
{
+ char *s, *e;
+ ulong reg;
+
+
if (!NetTxPacket)
{
int i;
+ ulong DecrementerSpeed;
/*
* Setup packet buffers, aligned correctly.
NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
for (i = 0; i < PKTBUFSRX; i++) {
NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE;
-
}
+
+ DecrementerSpeed = bis->bi_busfreq * 1000000 / 4;
+ tb_factor = 0xffffffff / (DecrementerSpeed / HZ);
+
}
eth_halt();
*/
NetOurIP = 0;
- /*
- * Make sure we have a network adapter.
-
- if (!NetCard && !NetInit())
- return;
- */
+ BootpTry = 0;
+ RarpTry = 0;
restart:
NetState = NETLOOP_CONTINUE;
* Start the ball rolling with the given start function. From
* here on, this code is a state machine driven by received
* packets and timer events.
-
- (*start_func)();
- eth_send(opacket, 100);
*/
- BootpRequest(fileName, loadAdr);
+ switch (protocol) {
+
+ case TFTP:
+ NetCopyEther(NetServerEther, NetBcastAddr);
+ strcpy(BootFile, fileName);
+ NetOurIP = bis->bi_ip_addr;
+ NetServerIP = 0;
+ s = getenv ("serverip");
+ for (reg=0; reg<4; ++reg) {
+ ulong val = s ? simple_strtoul(s, &e, 10) : 0;
+ NetServerIP <<= 8;
+ NetServerIP |= (val & 0xFF);
+ if (s) s = (*e) ? e+1 : e;
+ }
+ if (NetOurIP & NetServerIP) {
+ TftpStart(loadAdr);
+ } else {
+ printf("\nThis command requires valid IP addresses for Server (serverip)\nand client (ipaddr) in the environment!\n");
+ return 0;
+ }
+ break;
+
+ case RARP:
+ RarpRequest(fileName, loadAdr);
+ break;
+
+ default:
+ BootpRequest(fileName, loadAdr);
+ break;
+ }
+
/*
* Main packet reception loop. Loop receiving packets until
* Check the ethernet for a new packet. The ethernet
* receive routine will process it.
*/
- eth_rx();
+ eth_rx();
/*
* Check the keyboard for a Key. Quit if we get one.
/*
* Check for a timeout, and run the timeout handler
* if we have one.
-
+ */
if (timeHandler && GetTicksSinceBoot() > timeValue)
{
thand_f * x;
timeHandler = (thand_f *)0;
(*x)();
}
- */
+
switch (NetState)
{
goto restart;
case NETLOOP_SUCCESS:
- eth_halt();
+ eth_halt();
return 1;
case NETLOOP_FAIL:
{
NetServerIP = 0;
NetOurIP = 0;
- NetSetTimeout(60 * HZ, startAgainTimeout);
+ NetSetTimeout(10 * HZ, startAgainTimeout);
NetSetHandler(startAgainHandler);
}
else
{
timeHandler = f;
-/* timeValue = GetTicksSinceBoot() + iv; */
+ timeValue = GetTicksSinceBoot() + iv;
}
}
eth_send(pkt, len);
}
-#if 0
-void
-NetReceive(volatile uchar * pkt, int len)
-{
-et_dump ((et_mac_addr_t *)pkt);
-}
-#endif
-
-
void
arp = (ARP_t *)ip;
if (len < ARP_HDR_SIZE)
{
-/* #if 0*/
- printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
-/*#endif*/
+ printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
return;
}
if (SWAP16(arp->ar_op) != ARPOP_REQUEST)
NetSendPacket((uchar *)et, ((uchar *)arp - pkt) + ARP_HDR_SIZE);
break;
+ case PROT_RARP:
+#ifdef ET_DEBUG
+ printf("Got RARP\n");
+#endif
+ arp = (ARP_t *)ip;
+ if (len < ARP_HDR_SIZE)
+ {
+ printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
+ return;
+ }
+
+ if ((SWAP16(arp->ar_op) != RARPOP_REPLY) ||
+ (SWAP16(arp->ar_hrd) != ARP_ETHER) ||
+ (SWAP16(arp->ar_pro) != PROT_IP) ||
+ (arp->ar_hln != 6) || (arp->ar_pln != 4))
+
+ printf("invalid RARP header\n");
+ else
+ {
+ NetOurIP = *((IPaddr_t *)&arp->ar_data[16]);
+ NetServerIP = *((IPaddr_t *)&arp->ar_data[6]);
+ NetCopyEther(NetServerEther, &arp->ar_data[0]);
+
+ (*packetHandler)(0,0,0,0);
+ }
+ break;
+
case PROT_IP:
#ifdef ET_DEBUG
printf("Got IP\n");
return;
if (len < SWAP16(ip->ip_len))
{
-/*#if 0*/
printf("len bad %d < %d\n", len, SWAP16(ip->ip_len));
-/*#endif*/
return;
}
len = SWAP16(ip->ip_len);
return;
if (!NetCksumOk((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2))
{
-/*#if 0*/
printf("checksum bad\n");
-/*#endif*/
return;
}
if (NetOurIP && ip->ip_dst != NetOurIP)
if (ip->ip_p != 17) /* Only UDP packets */
return;
+
+ /* if at this point we still use the ET broadcast address
+ * copy the server ET adress to the req. location;
+ * this happens when issuing a TFTP request with the
+ * known server IP address and the ET broadcast address as destin.
+ */
+ if (memcmp(NetServerEther, NetBcastAddr, 6) == 0)
+ NetCopyEther(NetServerEther, et->et_src);
+
/*
* IP header OK. Pass the packet to the current handler.
*/
SWAP16(ip->udp_dst),
SWAP16(ip->udp_src),
SWAP16(ip->udp_len) - 8);
+
break;
}
}
(int)((x >> 8) & 0xff),
(int)((x >> 0) & 0xff));
}
+
+
+/*
+ * Return the number of HZ ticks since we started.
+ */
+ulong
+GetTicksSinceBoot(void)
+{
+ ulong l;
+ ulong h;
+ ulong tmp;
+ unsigned long long tb;
+
+ asm volatile (" 1: mftbu %0;
+ mftb %1;
+ mftbu %2;
+ cmpw %0, %2;
+ bne 1b
+ " : "=r" (h), "=r" (l), "=r" (tmp));
+
+ tb = (unsigned long long)h << 32 | (unsigned long long)l;
+ tb *= tb_factor;
+ l = tb >> 32;
+
+ return l;
+}
* (See License)
*/
-/* #include "limon.h" */
#include "ppcboot.h"
#include "net.h"
#include "tftp.h"
#define WELL_KNOWN_PORT 69 /* Well known TFTP port # */
-#define TIMEOUT 6 /* Seconds to timeout for a lost pkt */
+#define TIMEOUT 2 /* Seconds to timeout for a lost pkt */
#define TIMEOUT_COUNT 10 /* # of timeouts before giving up */
/* (for checking the image size) */
#define NDOTS 65 /* Number of "loading" dots */
return;
len -= 2;
TftpBlock = SWAP16(*(ushort *)pkt);
- printf("#");
+ if (((TftpBlock - 1) % 10) == 0) printf("#");
if (TftpState == STATE_RRQ)
{
}
else
{
- printf("t\b");
+ printf("T ");
NetSetTimeout(TIMEOUT * HZ, TftpTimeout);
TftpSend();
}
NetServerEther[5]);
#endif /* DEBUG */
- printf("BOOTP/TFTP from server ");
+ printf("TFTP from server ");
NetPrintIPaddr(NetServerIP);
printf("; our IP address is ");
NetPrintIPaddr(NetOurIP);
TftpServerPort = WELL_KNOWN_PORT;
TftpTimeoutCount = 0;
TftpState = STATE_RRQ;
- TftpOurPort = 1024 /*+ (GetTicksSinceBoot() % 3072)*/;
+ TftpOurPort = 1024 + (GetTicksSinceBoot() % 3072);
TftpSend();
}