]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
* Update LWMON keyboard initialization: we've been told to ignore
authorwdenk <wdenk>
Sun, 29 Sep 2002 15:38:05 +0000 (15:38 +0000)
committerwdenk <wdenk>
Sun, 29 Sep 2002 15:38:05 +0000 (15:38 +0000)
  "Hard Reset" and "Brownout" errors after a reset (when should we
  check for brownout, then?), and we have to scan the keyboard until
  it stabilizes.

* Re-arrange initialization sequence: move all getenv() calls that
  are not strictly necessary earlier to the "run from RAM" part of
  the code. This gives a measurable acceleration of boot time on
  systems where getenv_r() is slow (like systems storing the
  environment in slow EEPROM devices).

* Fix soft-i2c driver (according to the I2C protocol, a device has
  one I2C clock cycle to respond with ACK. If the device is "slow" or
  for some other reason it fails to assert ACK within one I2C cycle,
  it basically means NOT-ACK. The driver waited only half of the time
  it was supposed to wait (less than one clock).

* Patch by Kenneth Johansson, 20 Sep 2002:
  Implement chpart and fix the other commands for jffs according to
  doc/command

12 files changed:
CHANGELOG
board/lwmon/lwmon.c
board/trab/flash.c
common/cmd_jffs2.c
common/command.c
common/soft_i2c.c
cpu/mpc8260/cpu_init.c
doc/README.commands
include/cmd_jffs2.h
include/configs/smdk2400.h
include/configs/trab.h
lib_ppc/board.c

index dccbfdd8917a207fbe0463727c30b4f02ded2c8d..24df38e13d4a9672400cd2a7f1a78ade4b087ea1 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,27 @@
 Modifications for 1.2.0:
 ======================================================================
 
+* Update LWMON keyboard initialization: we've been told to ignore
+  "Hard Reset" and "Brownout" errors after a reset (when should we
+  check for brownout, then?), and we have to scan the keyboard until
+  it stabilizes.
+
+* Re-arrange initialization sequence: move all getenv() calls that
+  are not strictly necessary earlier to the "run from RAM" part of
+  the code. This gives a measurable acceleration of boot time on
+  systems where getenv_r() is slow (like systems storing the
+  environment in slow EEPROM devices).
+
+* Fix soft-i2c driver (according to the I2C protocol, a device has
+  one I2C clock cycle to respond with ACK. If the device is "slow" or
+  for some other reason it fails to assert ACK within one I2C cycle,
+  it basically means NOT-ACK. The driver waited only half of the time
+  it was supposed to wait (less than one clock).
+
+* Patch by Kenneth Johansson, 20 Sep 2002:
+  Implement chpart and fix the other commands for jffs according to
+  doc/command
+
 * Fix environment problems on SMDK2400 and TRAB boards;
   Make environment layout backward compatible when no redundancy is
   used
index e8176b5ac1d1fbb6fed13568a124b3ac8016cd8b..75ab80009e403e88106e790d2587c5bf800a8344 100644 (file)
@@ -363,6 +363,12 @@ void reset_phy (void)
 
 /* status codes */
 #define KEYBD_STATUS_MASK      0x3F
+#define        KEYBD_STATUS_H_RESET    0x20
+#define KEYBD_STATUS_BROWNOUT  0x10
+#define KEYBD_STATUS_WD_RESET  0x08
+#define KEYBD_STATUS_OVERLOAD  0x04
+#define KEYBD_STATUS_ILLEGAL_WR        0x02
+#define KEYBD_STATUS_ILLEGAL_RD        0x01
 
 /* Number of bytes returned from Keyboard Controller */
 #define KEYBD_VERSIONLEN       2       /* version information */
@@ -379,6 +385,7 @@ static uchar *key_match (uchar *);
 int misc_init_r (void)
 {
        uchar kbd_data[KEYBD_DATALEN];
+       uchar tmp_data[KEYBD_DATALEN];
        uchar keybd_env[2 * KEYBD_DATALEN + 1];
        uchar val, errcd;
        uchar *str;
@@ -390,14 +397,18 @@ int misc_init_r (void)
        val = KEYBD_CMD_READ_STATUS;
        i2c_write (kbd_addr, 0, 0, &val, 1);
        i2c_read (kbd_addr, 0, 0, &errcd, 1);
-       errcd &= KEYBD_STATUS_MASK;     /* clear unused bits */
+       /* clear unused bits */
+       errcd &= KEYBD_STATUS_MASK;
+       /* clear "irrelevant" bits. Recommended by Martin Rajek, LWN */
+       errcd &= ~(KEYBD_STATUS_H_RESET|KEYBD_STATUS_BROWNOUT);
        if (errcd) {
                printf ("KEYBD: Error %02X\n", errcd);
        }
        /* Reset error code and verify */
        val = KEYBD_CMD_RESET_ERRORS;
        i2c_write (kbd_addr, 0, 0, &val, 1);
-       udelay(1000);
+       udelay(1000);   /* delay NEEDED by keyboard PIC !!! */
+
        val = KEYBD_CMD_READ_STATUS;
        i2c_write (kbd_addr, 0, 0, &val, 1);
        i2c_read (kbd_addr, 0, 0, &val, 1);
@@ -426,10 +437,32 @@ int misc_init_r (void)
        i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_VERSIONLEN);
        printf ("KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]);
 
-       /* Read keys */
-       val = KEYBD_CMD_READ_KEYS;
-       i2c_write (kbd_addr, 0, 0, &val, 1);
-       i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+       /*
+        * Read current keyboard state.
+        *
+         * After the error reset it may take some time before the
+         * keyboard PIC picks up a valid keyboard scan - the total
+         * scan time is approx. 1.6 ms (information by Martin Rajek,
+         * 28 Sep 2002). We read a couple of times for the keyboard
+         * to stabilize, using a big enough delay.
+         * 10 times should be enough. If the data is still changing,
+         * we use what we get :-(
+        */
+
+       memset (tmp_data, 0xFF, KEYBD_DATALEN); /* impossible value */
+       for (i=0; i<10; ++i) {
+               val = KEYBD_CMD_READ_KEYS;
+               i2c_write (kbd_addr, 0, 0, &val, 1);
+               i2c_read (kbd_addr, 0, 0, kbd_data, KEYBD_DATALEN);
+
+               if (memcmp(kbd_data, tmp_data, KEYBD_DATALEN) == 0) {
+                       /* consistent state, done */
+                       break;
+               }
+               /* remeber last state, delay, and retry */
+               memcpy (tmp_data, kbd_data, KEYBD_DATALEN);
+               udelay (5);
+       }
 
        for (i = 0; i < KEYBD_DATALEN; ++i) {
                sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
index 03806c23079a78650b913732c49719565098804d..5a8bb81cb5b6501c7c93d1e76a52aee5776cef1c 100644 (file)
@@ -123,7 +123,7 @@ void flash_print_info (flash_info_t * info)
 
        switch (info->flash_id & FLASH_TYPEMASK) {
        case (AMD_ID_LV320B & FLASH_TYPEMASK):
-               printf ("2x Am29F320BB (32Mbit)\n");
+               printf ("2x Am29LV320DB (32Mbit)\n");
                break;
        default:
                printf ("Unknown Chip Type\n");
index 99271e148ac89514e1f87408cbd19c9b1384deab..a2b5ebf69ea4e8bd921421cb9623b108da2ec77f 100644 (file)
@@ -34,6 +34,7 @@
 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
 
 #include <jffs2/jffs2.h>
+static int part_num=0;
 
 #ifndef CFG_JFFS_CUSTOM_PART
 
@@ -44,44 +45,48 @@ jffs2_part_info(int part_num)
 {
        extern flash_info_t flash_info[];       /* info for FLASH chips */
        int i;
+
+       if(part_num==0){
        
-       if(part.usr_priv==(void*)1)
-               return &part;
+               if(part.usr_priv==(void*)1)
+                       return &part;
        
-       memset(&part, 0, sizeof(part));
+               memset(&part, 0, sizeof(part));
 
 #if defined(CFG_JFFS2_FIRST_SECTOR)
-       part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR];
+               part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR];
 #else
-       part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+               part.offset = (unsigned char *) flash_info[CFG_JFFS2_FIRST_BANK].start[0];
 #endif
 
-       /* Figure out flash partition size */
-       for (i = CFG_JFFS2_FIRST_BANK; i < CFG_JFFS2_NUM_BANKS+CFG_JFFS2_FIRST_BANK; i++)
-           part.size += flash_info[i].size;
+               /* Figure out flash partition size */
+               for (i = CFG_JFFS2_FIRST_BANK; i < CFG_JFFS2_NUM_BANKS+CFG_JFFS2_FIRST_BANK; i++)
+                       part.size += flash_info[i].size;
 
 #if defined(CFG_JFFS2_FIRST_SECTOR) && (CFG_JFFS2_FIRST_SECTOR > 0)
-       part.size -=
-            flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR] -
-            flash_info[CFG_JFFS2_FIRST_BANK].start[0];
+               part.size -=
+                       flash_info[CFG_JFFS2_FIRST_BANK].start[CFG_JFFS2_FIRST_SECTOR] -
+                       flash_info[CFG_JFFS2_FIRST_BANK].start[0];
 #endif
 
-       /* unused in current jffs2 loader */
-       part.erasesize = 0;
+               /* unused in current jffs2 loader */
+               part.erasesize = 0;
 
-       /* Mark the struct as ready */
-       part.usr_priv=(void*)1;
+               /* Mark the struct as ready */
+               part.usr_priv=(void*)1;
 
-       return &part;
+               return &part;
+       }
+       return 0;
 }
 #endif /* ifndef CFG_JFFS_CUSTOM_PART */
-
 int
 do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
        char *filename = "vmlinuz";
        ulong offset = CFG_LOAD_ADDR;
        int size;
+       struct part_info *part;
 
        if (argc >= 2) {
                offset = simple_strtoul(argv[1], NULL, 16);
@@ -89,41 +94,82 @@ do_jffs2_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        if (argc == 3) {
                filename = argv[2];
        }
+       
+       if (0 != (part=jffs2_part_info(part_num))){ 
 
-       printf("### JFFS2 loading '%s' to 0x%lx\n", filename, offset);
-       size = jffs2_1pass_load((char *)offset, jffs2_part_info(0), filename);
+               printf("### JFFS2 loading '%s' to 0x%lx\n", filename, offset);
+               size = jffs2_1pass_load((char *)offset, part, filename);
 
-       if (size > 0) {
-           printf("### JFFS2 load compleate: %d bytes loaded to 0x%lx\n",
-                                       size, offset);
-       } else {
-           printf("### JFFS2 LOAD ERROR<%x> for %s!\n", size, filename);
+               if (size > 0) {
+                       printf("### JFFS2 load compleate: %d bytes loaded to 0x%lx\n",
+                              size, offset);
+               } else {
+                       printf("### JFFS2 LOAD ERROR<%x> for %s!\n", size, filename);
+               }
+
+               return !(size > 0);
        }
-       return !(size > 0);
+       printf("Active partition not valid\n");
+       return 0;
 }
 
 int
-do_jffs2_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+do_jffs2_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
        char *filename = "/";
        int ret;
+       struct part_info *part;
 
        if (argc == 2)
-           filename = argv[1];
+               filename = argv[1];
+
+       if (0 != (part=jffs2_part_info(part_num))){ 
 
-       ret = jffs2_1pass_ls(jffs2_part_info(0), filename);
+               ret = jffs2_1pass_ls(jffs2_part_info(part_num), filename);
 
-       return (ret == 1);
+               return (ret == 1);
+       }
+       printf("Active partition not valid\n");
+       return 0;
 }
 
 int
 do_jffs2_fsinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
        int ret;
+       struct part_info *part;
 
-       ret = jffs2_1pass_info(jffs2_part_info(0));
+       if (0 != (part=jffs2_part_info(part_num))){ 
 
-       return (ret == 1);
+               ret = jffs2_1pass_info(jffs2_part_info(part_num));
+
+               return (ret == 1);
+       }
+       printf("Active partition not valid\n");
+       return 0;
 }
 
+int
+do_jffs2_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       int tmp_part;
+       
+       if (argc >= 2) {
+               tmp_part = simple_strtoul(argv[1], NULL, 16);
+       }else{
+               printf("Need partition number in argument list\n");
+               return 0;
+                       
+       }
+
+       if (jffs2_part_info(tmp_part)){
+               printf("Partiton changed to %d\n",tmp_part);
+               part_num=tmp_part;
+               return 0;
+       }
+
+       printf("Partition %d is not valid partiton\n",tmp_part);                
+       return 0;
+
+}
 #endif /* CFG_CMD_JFFS2 */
index 541f19fa873e6f106e9805abe0ff7c69f919fcc6..af9ea6b546e933c1f4988b159b8c3bbd89995f41 100644 (file)
@@ -228,6 +228,7 @@ cmd_tbl_t cmd_tbl[] = {
        CMD_TBL_BREAK
        CMD_TBL_BRGINFO
        CMD_TBL_CARINFO
+       CMD_TBL_JFFS2_CHPART
        CMD_TBL_CMP
        CMD_TBL_CONINFO
        CMD_TBL_CONTINUE
@@ -250,6 +251,8 @@ cmd_tbl_t cmd_tbl[] = {
        CMD_TBL_FDC
        CMD_TBL_FLINFO
        CMD_TBL_FPGA
+       CMD_TBL_JFFS2_FSINFO
+       CMD_TBL_JFFS2_FSLOAD
        CMD_TBL_GETDCR
        CMD_TBL_GO
        CMD_TBL_HELP
@@ -272,11 +275,11 @@ cmd_tbl_t cmd_tbl[] = {
        CMD_TBL_IOPINFO
        CMD_TBL_IOPSET
        CMD_TBL_IRQINFO
-       CMD_TBL_JFFS2
        CMD_TBL_KGDB
        CMD_TBL_LOADB
        CMD_TBL_LOADS
        CMD_TBL_LOOP
+       CMD_TBL_JFFS2_LS
        CMD_TBL_MCCINFO
        CMD_TBL_MD
        CMD_TBL_MEMCINFO
index ce8ec4b8edba834cb2bbe54d95e4f1c7229bbd82..18a460ca37450c29a940eb79e317e16f1667566d 100644 (file)
@@ -204,14 +204,16 @@ static int write_byte(uchar data)
         */
        I2C_SCL(0);
        I2C_DELAY;
+       I2C_SDA(1);
        I2C_TRISTATE;
        I2C_DELAY;
        I2C_SCL(1);
        I2C_DELAY;
+       I2C_DELAY;
        nack = I2C_READ;
-       I2C_SDA(0);
-       I2C_ACTIVE;
+       I2C_SCL(0);
        I2C_DELAY;
+       I2C_ACTIVE;
 
        return(nack);   /* not a nack is an ack */
 }
index 58b8c9874ec69906de8b04aebffacb427b1432bc..d6a1600876e7a0b8a27a52768a93b8db998bcf7c 100644 (file)
@@ -102,6 +102,12 @@ void cpu_init_f (volatile immap_t * immr)
        volatile memctl8260_t *memctl = &immr->im_memctl;
        extern void m8260_cpm_reset (void);
 
+       /* Pointer is writable since we allocated a register for it */
+       gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
+                
+       /* Clear initial global data */
+       memset ((void *) gd, 0, sizeof (gd_t));
+                       
        /* RSR - Reset Status Register - clear all status (5-4) */
        gd->reset_status = immr->im_clkrst.car_rsr;
        immr->im_clkrst.car_rsr = RSR_ALLBITS;
index 4a7fecd18353e7018ebc4eb4728f8e97f63e6ed2..539d4b61b5de895b28ab20ad5c3c0a2ca5f2a814 100644 (file)
@@ -23,6 +23,7 @@ bootd         4
 break          2
 brginfo                3
 carinfo                3
+chpart         6
 cmp            3
 coninfo                5
 continue       4
@@ -41,6 +42,8 @@ fccinfo               3
 fdcboot                4
 flinfo         3
 fpga           4
+fsinfo         5 
+fsload         5
 getdcr         6               # IBM 4XX DCR registers
 go             2
 help           1
@@ -56,6 +59,7 @@ kgdb          4
 loadb          5
 loads          5
 loop           4
+ls             2
 mccinfo                3
 md             2
 memcinfo       4
index 5b16bc76bf7bd9afe2812436c33dd0e7cfb96071..670455b47a0a91c294706588bb2c6e72977c7ce9 100644 (file)
 #define        _CMD_JFFS2_H
 
 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2)
-#define        CMD_TBL_JFFS2   MK_CMD_TBL_ENTRY(                               \
+
+#define        CMD_TBL_JFFS2_FSLOAD    MK_CMD_TBL_ENTRY(                       \
        "fsload",       5,      3,      0,      do_jffs2_fsload,        \
-       "fsload  - load binary file from a filesystem image\n", \
+       "fsload  - load binary file from a filesystem image\n",         \
        "[ off ] [ filename ]\n"                                        \
        "    - load binary file from flash bank\n"                      \
        "      with offset 'off'\n"                                     \
-),                                                                     \
-       MK_CMD_TBL_ENTRY(                                               \
+),
+
+#define CMD_TBL_JFFS2_FSINFO           MK_CMD_TBL_ENTRY(                       \
        "fsinfo",       5,      1,      1,      do_jffs2_fsinfo,        \
        "fsinfo  - print information about filesystems\n",              \
-       "\n"                                                            \
        "    - print information about filesystems\n"                   \
-),                                                                     \
-       MK_CMD_TBL_ENTRY(                                               \
+),
+
+#define CMD_TBL_JFFS2_LS       MK_CMD_TBL_ENTRY(                       \
        "ls",           2,      2,      1,      do_jffs2_ls,            \
        "ls      - list files in a directory (default /)\n",            \
        "[ directory ]\n"                                               \
        "    - list files in a directory.\n"                            \
 ),
 
+#define CMD_TBL_JFFS2_CHPART           MK_CMD_TBL_ENTRY(                       \
+       "chpart",       6,      2,      0,      do_jffs2_chpart,        \
+       "chpart  - change active partition\n",                          \
+       "    - change active partition\n"                               \
+),
+
 int do_jffs2_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 int do_jffs2_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 int do_jffs2_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
-
+int do_jffs2_chpart (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 #else
-#define CMD_TBL_JFFS2
+#define        CMD_TBL_JFFS2_FSLOAD
+#define CMD_TBL_JFFS2_FSINFO
+#define CMD_TBL_JFFS2_LS
+#define CMD_TBL_JFFS2_CHPART
 #endif /* CFG_CMD_JFFS2 */
 
 #endif /* _CMD_JFFS2_H */
index 445add33a6595d044d06bd1c1418ebf27ad4d133..9ddf44836ef3fc0f49cb42d6e24a308e34eef650 100644 (file)
  * (easy to change)
  */
 #define CONFIG_ARM920T         1       /* This is an ARM920T core      */
-#define CONFIG_S3C2400         1       /* in a SAMSUNG S3C2400 SoC     */
+#define CONFIG_S3C2400         1       /* in a SAMSUNG S3C2400 SoC     */
 #define CONFIG_SMDK2400                1       /* on an SAMSUNG SMDK2400 Board */
 
-#undef CONFIG_USE_IRQ                  /* we don't need IRQ/FIQ stuff */
+#undef CONFIG_USE_IRQ                  /* we don't need IRQ/FIQ stuff  */
+
+#define CONFIG_CMDLINE_TAG      1      /* enable passing of ATAGs      */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG       1
+
 
 /*
  * Size of malloc() pool
index b288c8d1809f93c9707ce9d5d82182f082d3142b..508e57e61cf473783e29086a9c76a571edfdf5bc 100644 (file)
 
 #undef CONFIG_USE_IRQ                  /* we don't need IRQ/FIQ stuff */
 
+#define CONFIG_CMDLINE_TAG      1      /* enable passing of ATAGs      */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_INITRD_TAG       1
+
 /*
  * Size of malloc() pool
  */
index ef5a7fcd7bdda717ad855b40eda67745fa966fb3..a4a91ac639f2bd77d31c6b03619a6484b326b61e 100644 (file)
@@ -324,18 +324,17 @@ void board_init_f (ulong bootflag)
        DECLARE_GLOBAL_DATA_PTR;
 
        bd_t *bd;
-       ulong reg, len, addr, addr_sp;
-       int i;
+       ulong len, addr, addr_sp;
        gd_t *id;
-       char *s, *e;
-       uchar tmp[64];          /* long enough for environment variables */
        init_fnc_t **init_fnc_ptr;
 
        /* Pointer is writable since we allocated a register for it */
        gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET);
 
+#ifndef CONFIG_8260
        /* Clear initial global data */
        memset ((void *) gd, 0, sizeof (gd_t));
+#endif
 
        for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
                if ((*init_fnc_ptr) () != 0) {
@@ -472,56 +471,6 @@ void board_init_f (ulong bootflag)
        bd->bi_bootflags = bootflag;    /* boot / reboot flag (for LynxOS)    */
 
        WATCHDOG_RESET ();
-
-       i = getenv_r ("ethaddr", tmp, sizeof (tmp));
-       s = (i > 0) ? tmp : NULL;
-
-#if defined (CONFIG_MBX) || defined (CONFIG_RPXCLASSIC) || defined(CONFIG_IAD210)
-       if (s == NULL)
-               board_get_enetaddr (bd->bi_enetaddr);
-       else
-#endif
-               for (reg = 0; reg < 6; ++reg) {
-                       bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
-                       if (s)
-                               s = (*e) ? e + 1 : e;
-               }
-#ifdef CONFIG_HERMES
-       if ((gd->board_type >> 16) == 2)
-               bd->bi_ethspeed = gd->board_type & 0xFFFF;
-       else
-               bd->bi_ethspeed = 0xFFFF;
-#endif
-
-#ifdef CONFIG_NX823
-       load_sernum_ethaddr ();
-#endif
-
-#if defined(CFG_GT_6426x) || defined(CONFIG_PN62)
-       /* handle the 2nd ethernet address */
-
-       i = getenv_r ("eth1addr", tmp, sizeof (tmp));
-       s = (i > 0) ? tmp : NULL;
-
-       for (reg = 0; reg < 6; ++reg) {
-               bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
-               if (s)
-                       s = (*e) ? e + 1 : e;
-       }
-#endif
-#if defined(CFG_GT_6426x)
-       /* handle the 3rd ethernet address */
-
-       i = getenv_r ("eth2addr", tmp, sizeof (tmp));
-       s = (i > 0) ? tmp : NULL;
-
-       for (reg = 0; reg < 6; ++reg) {
-               bd->bi_enet2addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
-               if (s)
-                       s = (*e) ? e + 1 : e;
-       }
-#endif
-
        bd->bi_intfreq = gd->cpu_clk;   /* Internal Freq, in Hz */
        bd->bi_busfreq = gd->bus_clk;   /* Bus Freq,      in Hz */
 #if defined(CONFIG_8260)
@@ -580,8 +529,9 @@ void board_init_r (gd_t *id, ulong dest_addr)
        DECLARE_GLOBAL_DATA_PTR;
 
        cmd_tbl_t *cmdtp;
-       char *s;
+       char *s, *e;
        bd_t *bd;
+       int i;
        extern void malloc_bin_reloc (void);
 
 #ifndef CFG_NO_FLASH
@@ -601,6 +551,58 @@ void board_init_r (gd_t *id, ulong dest_addr)
 
        gd->reloc_off = dest_addr - CFG_MONITOR_BASE;
 
+       /*
+        * Fill in missing fields of bd_info.
+         * We do this here, where we have "normal" access to the
+         * environment; we used to do this still running from ROM,
+         * where had to use getenv_r(), which can be pretty slow when
+         * the environment is in EEPROM.
+        */
+       s = getenv ("ethaddr");
+#if defined (CONFIG_MBX) || defined (CONFIG_RPXCLASSIC) || defined(CONFIG_IAD210)
+       if (s == NULL)
+               board_get_enetaddr (bd->bi_enetaddr);
+       else
+#endif
+               for (i = 0; i < 6; ++i) {
+                       bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
+                       if (s)
+                               s = (*e) ? e + 1 : e;
+               }
+#ifdef CONFIG_HERMES
+       if ((gd->board_type >> 16) == 2)
+               bd->bi_ethspeed = gd->board_type & 0xFFFF;
+       else
+               bd->bi_ethspeed = 0xFFFF;
+#endif
+
+#ifdef CONFIG_NX823
+       load_sernum_ethaddr ();
+#endif
+
+#if defined(CFG_GT_6426x) || defined(CONFIG_PN62)
+       /* handle the 2nd ethernet address */
+
+       s = getenv ("eth1addr");
+
+       for (reg = 0; reg < 6; ++reg) {
+               bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+               if (s)
+                       s = (*e) ? e + 1 : e;
+       }
+#endif
+#if defined(CFG_GT_6426x)
+       /* handle the 3rd ethernet address */
+
+       s = getenv ("eth2addr");
+
+       for (reg = 0; reg < 6; ++reg) {
+               bd->bi_enet2addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
+               if (s)
+                       s = (*e) ? e + 1 : e;
+       }
+#endif
+
        /*
         * We have to relocate the command table manually
         */