ppc4xx: Updates to Korat-specific code
authorLarry Johnson <lrj@acm.org>
Mon, 17 Mar 2008 16:10:35 +0000 (11:10 -0500)
committerStefan Roese <sr@denx.de>
Thu, 27 Mar 2008 09:52:03 +0000 (10:52 +0100)
This patch contains updates for changes for the Korat PPC440EPx board.
These changes include:

(1) Support for "permanent" and "upgradable" copies of U-Boot, as
described in the new "doc/README.korat" file;

(2) a new memory map for the registers in the board's CPLD;

(3) a revised format for manufacturer's data in serial EEPROM; and

(4) changes to track updates to U-Boot for the Sequoia board.

Signed-off-by: Larry Johnson <lrj@acm.org>
board/korat/config.mk
board/korat/init.S
board/korat/korat.c
board/korat/u-boot-F7FC.lds [new file with mode: 0644]
doc/README.korat [new file with mode: 0644]
include/configs/korat.h

index 39966e0..fa8374f 100644 (file)
 # Korat (PPC440EPx) board
 #
 
-TEXT_BASE = 0xFFFA0000
-
 PLATFORM_CPPFLAGS += -DCONFIG_440=1
 
 ifeq ($(debug),1)
 PLATFORM_CPPFLAGS += -DDEBUG
 endif
 
+ifeq ($(emul),1)
+PLATFORM_CPPFLAGS += -fno-schedule-insns -fno-schedule-insns2
+endif
+
 ifeq ($(dbcr),1)
-PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8cff0000
+PLATFORM_CPPFLAGS += -DCFG_INIT_DBCR=0x8CFF0000
+endif
+
+ifeq ($(perm),1)
+PLATFORM_CPPFLAGS += -DCONFIG_KORAT_PERMANENT
+TEXT_BASE = 0xFFFA0000
+else
+TEXT_BASE = 0xF7F60000
+LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-F7FC.lds
 endif
index bd0e8b4..bf8b2c8 100644 (file)
@@ -43,7 +43,7 @@ tlbtab:
         * BOOT_CS (FLASH) must be first. Before relocation SA_I can be off to use the
         * speed up boot process. It is patched after relocation to enable SA_I
         */
-       tlbentry( CFG_BOOT_BASE_ADDR, SZ_256M, CFG_BOOT_BASE_ADDR, 1, AC_R|AC_W|AC_X|SA_G )
+       tlbentry( 0xF0000000, SZ_256M, 0xF0000000, 1, AC_R|AC_W|AC_X|SA_G )
 
        /*
         * TLB entries for SDRAM are not needed on this platform.  They are
@@ -52,24 +52,32 @@ tlbtab:
 
 #ifdef CFG_INIT_RAM_DCACHE
        /* TLB-entry for init-ram in dcache (SA_I must be turned off!) */
-       tlbentry( CFG_INIT_RAM_ADDR, SZ_64K, CFG_INIT_RAM_ADDR, 0, AC_R|AC_W|AC_X|SA_G )
+       tlbentry( CFG_INIT_RAM_ADDR, SZ_64K, CFG_INIT_RAM_ADDR, 0,
+                 AC_R|AC_W|AC_X|SA_G )
 #endif
 
        /* TLB-entry for PCI Memory */
-       tlbentry( CFG_PCI_MEMBASE, SZ_256M, CFG_PCI_MEMBASE, 1, AC_R|AC_W|SA_G|SA_I )
-       tlbentry( CFG_PCI_MEMBASE1, SZ_256M, CFG_PCI_MEMBASE1, 1, AC_R|AC_W|SA_G|SA_I )
-       tlbentry( CFG_PCI_MEMBASE2, SZ_256M, CFG_PCI_MEMBASE2, 1, AC_R|AC_W|SA_G|SA_I )
-       tlbentry( CFG_PCI_MEMBASE3, SZ_256M, CFG_PCI_MEMBASE3, 1, AC_R|AC_W|SA_G|SA_I )
+       tlbentry( CFG_PCI_MEMBASE + 0x00000000, SZ_256M,
+                 CFG_PCI_MEMBASE + 0x00000000, 1, AC_R|AC_W|SA_G|SA_I )
+
+       tlbentry( CFG_PCI_MEMBASE + 0x10000000, SZ_256M,
+                 CFG_PCI_MEMBASE + 0x10000000, 1, AC_R|AC_W|SA_G|SA_I )
+
+       tlbentry( CFG_PCI_MEMBASE + 0x20000000, SZ_256M,
+                 CFG_PCI_MEMBASE + 0x20000000, 1, AC_R|AC_W|SA_G|SA_I )
+
+       tlbentry( CFG_PCI_MEMBASE + 0x30000000, SZ_256M,
+                 CFG_PCI_MEMBASE + 0x30000000, 1, AC_R|AC_W|SA_G|SA_I )
 
        /* TLB-entry for EBC */
        tlbentry( CFG_CPLD_BASE, SZ_1K, CFG_CPLD_BASE, 1, AC_R|AC_W|SA_G|SA_I )
 
        /* TLB-entry for Internal Registers & OCM */
        /* I wonder why this must be executable -- lrj@acm.org 2007-10-08 */
-       tlbentry( 0xE0000000, SZ_16M, 0xE0000000, 0,  AC_R|AC_W|AC_X|SA_I )
+       tlbentry( 0xE0000000, SZ_16M, 0xE0000000, 0, AC_R|AC_W|AC_X|SA_I )
 
        /*TLB-entry PCI registers*/
-       tlbentry( 0xEEC00000, SZ_1K, 0xEEC00000, 1,  AC_R|AC_W|SA_G|SA_I )
+       tlbentry( 0xEEC00000, SZ_1K, 0xEEC00000, 1, AC_R|AC_W|SA_G|SA_I )
 
        /* TLB-entry for peripherals */
        tlbentry( 0xEF000000, SZ_16M, 0xEF000000, 1, AC_R|AC_W|SA_G|SA_I)
@@ -78,3 +86,10 @@ tlbtab:
        tlbentry(0xE8000000, SZ_64K, 0xE8000000, 1, AC_R|AC_W|SA_G|SA_I)
 
        tlbtab_end
+
+#if defined(CONFIG_KORAT_PERMANENT)
+       .globl  korat_branch_absolute
+korat_branch_absolute:
+       mtlr    r3
+       blr
+#endif
index 90fd0a7..a7b4b27 100644 (file)
@@ -2,12 +2,12 @@
  * (C) Copyright 2007-2008
  * Larry Johnson, lrj@acm.org
  *
- * (C) Copyright 2006-2008
+ * (C) Copyright 2006-2007
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
  * (C) Copyright 2006
  * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
- * Alain Saurel,            AMCC/IBM, alain.saurel@fr.ibm.com
+ * Alain Saurel,           AMCC/IBM, alain.saurel@fr.ibm.com
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -39,12 +39,45 @@ extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
 
 ulong flash_get_size(ulong base, int banknum);
 
+#if defined(CONFIG_KORAT_PERMANENT)
+void korat_buzzer(int const on)
+{
+       if (on) {
+               out_8((u8 *) CFG_CPLD_BASE + 0x05,
+                     in_8((u8 *) CFG_CPLD_BASE + 0x05) | 0x80);
+       } else {
+               out_8((u8 *) CFG_CPLD_BASE + 0x05,
+                     in_8((u8 *) CFG_CPLD_BASE + 0x05) & ~0x80);
+       }
+}
+#endif
+
 int board_early_init_f(void)
 {
-       u32 sdr0_pfc1, sdr0_pfc2;
-       u32 reg;
+       uint32_t sdr0_pfc1, sdr0_pfc2;
+       uint32_t reg;
        int eth;
 
+#if defined(CONFIG_KORAT_PERMANENT)
+       unsigned mscount;
+
+       extern void korat_branch_absolute(uint32_t addr);
+
+       for (mscount = 0;  mscount < CFG_KORAT_MAN_RESET_MS; ++mscount) {
+               udelay(1000);
+               if (gpio_read_in_bit(CFG_GPIO_RESET_PRESSED_)) {
+                       /* This call does not return. */
+                       korat_branch_absolute(
+                               CFG_FLASH1_TOP - 2 * CFG_ENV_SECT_SIZE - 4);
+               }
+       }
+       korat_buzzer(1);
+       while (!gpio_read_in_bit(CFG_GPIO_RESET_PRESSED_))
+               udelay(1000);
+
+       korat_buzzer(0);
+#endif
+
        mtdcr(ebccfga, xbcfg);
        mtdcr(ebccfgd, 0xb8400000);
 
@@ -75,8 +108,11 @@ int board_early_init_f(void)
        mtdcr(uic2vr, 0x00000000);      /* int31 highest, base=0x000 */
        mtdcr(uic2sr, 0xffffffff);      /* clear all */
 
-       /* take sim card reader and CF controller out of reset */
-       out_8((u8 *) CFG_CPLD_BASE + 0x04, 0x80);
+       /*
+        * Take sim card reader and CF controller out of reset.  Also enable PHY
+        * auto-detect until board-specific PHY resets are available.
+        */
+       out_8((u8 *) CFG_CPLD_BASE + 0x02, 0xC0);
 
        /* Configure the two Ethernet PHYs.  For each PHY, configure for fiber
         * if the SFP module is present, and for copper if it is not present.
@@ -85,8 +121,8 @@ int board_early_init_f(void)
                if (gpio_read_in_bit(CFG_GPIO_SFP0_PRESENT_ + eth)) {
                        /* SFP module not present: configure PHY for copper. */
                        /* Set PHY to autonegotate 10 MB, 100MB, or 1 GB */
-                       out_8((u8 *) CFG_CPLD_BASE + 0x06,
-                             in_8((u8 *) CFG_CPLD_BASE + 0x06) |
+                       out_8((u8 *) CFG_CPLD_BASE + 0x03,
+                             in_8((u8 *) CFG_CPLD_BASE + 0x03) |
                              0x06 << (4 * eth));
                } else {
                        /* SFP module present: configure PHY for fiber and
@@ -99,10 +135,18 @@ int board_early_init_f(void)
        gpio_write_bit(CFG_GPIO_PHY0_EN, 1);
        gpio_write_bit(CFG_GPIO_PHY1_EN, 1);
 
-       /* select Ethernet pins */
+       /* Wait 1 ms, then enable Fiber signal detect to PHYs. */
+       udelay(1000);
+       out_8((u8 *) CFG_CPLD_BASE + 0x03,
+             in_8((u8 *) CFG_CPLD_BASE + 0x03) | 0x88);
+
+       /* select Ethernet (and optionally IIC1) pins */
        mfsdr(SDR0_PFC1, sdr0_pfc1);
        sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SELECT_MASK) |
                SDR0_PFC1_SELECT_CONFIG_4;
+#ifdef CONFIG_I2C_MULTI_BUS
+       sdr0_pfc1 |= ((sdr0_pfc1 & ~SDR0_PFC1_SIS_MASK) | SDR0_PFC1_SIS_IIC1_SEL);
+#endif
        mfsdr(SDR0_PFC2, sdr0_pfc2);
        sdr0_pfc2 = (sdr0_pfc2 & ~SDR0_PFC2_SELECT_MASK) |
                SDR0_PFC2_SELECT_CONFIG_4;
@@ -116,6 +160,58 @@ int board_early_init_f(void)
        return 0;
 }
 
+/*
+ * The boot flash on CS0 normally has its write-enable pin disabled, and so will
+ * not respond to CFI commands.  This routine therefore fills in the flash
+ * information for the boot flash.  (The flash at CS1 operates normally.)
+ */
+ulong board_flash_get_legacy (ulong base, int banknum, flash_info_t * info)
+{
+       uint32_t addr;
+       int i;
+
+       if (1 != banknum)
+               return 0;
+
+       info->size              = CFG_FLASH0_SIZE;
+       info->sector_count      = CFG_FLASH0_SIZE / 0x20000;
+       info->flash_id          = 0x01000000;
+       info->portwidth         = 2;
+       info->chipwidth         = 2;
+       info->buffer_size       = 32;
+       info->erase_blk_tout    = 16384;
+       info->write_tout        = 2;
+       info->buffer_write_tout = 5;
+       info->vendor            = 2;
+       info->cmd_reset         = 0x00F0;
+       info->interface         = 2;
+       info->legacy_unlock     = 0;
+       info->manufacturer_id   = 1;
+       info->device_id         = 0x007E;
+
+#if CFG_FLASH0_SIZE == 0x01000000
+       info->device_id2        = 0x2101;
+#elif CFG_FLASH0_SIZE == 0x04000000
+       info->device_id2        = 0x2301;
+#else
+#error Unable to set device_id2 for current CFG_FLASH0_SIZE
+#endif
+
+       info->ext_addr          = 0x0040;
+       info->cfi_version       = 0x3133;
+       info->cfi_offset        = 0x0055;
+       info->addr_unlock1      = 0x00000555;
+       info->addr_unlock2      = 0x000002AA;
+       info->name              = "CFI conformant";
+       for (i = 0, addr = -info->size;
+            i < info->sector_count;
+            ++i, addr += 0x20000) {
+               info->start[i] = addr;
+               info->protect[i] = 0x00;
+       }
+       return 1;
+}
+
 static int man_data_read(unsigned int addr)
 {
        /*
@@ -189,12 +285,20 @@ static void set_serial_number(void)
         * If the environmental variable "serial#" is not set, try to set it
         * from the manufacturer's information serial EEPROM.
         */
-       char s[MAN_SERIAL_NO_LENGTH + 1];
+       char s[MAN_INFO_LENGTH + MAN_MAC_ADDR_LENGTH + 2];
+
+       if (getenv("serial#"))
+               return;
+
+       if (!man_data_read_field(s, MAN_INFO_FIELD, MAN_INFO_LENGTH))
+               return;
+
+       s[MAN_INFO_LENGTH] = '-';
+       if (!man_data_read_field(s + MAN_INFO_LENGTH + 1, MAN_MAC_ADDR_FIELD,
+                                MAN_MAC_ADDR_LENGTH))
+               return;
 
-       if (0 == getenv("serial#") &&
-           0 != man_data_read_field(s, MAN_SERIAL_NO_FIELD,
-                                    MAN_SERIAL_NO_LENGTH))
-               setenv("serial#", s);
+       setenv("serial#", s);
 }
 
 static void set_mac_addresses(void)
@@ -204,45 +308,58 @@ static void set_mac_addresses(void)
         * set, try to set them from the manufacturer's information serial
         * EEPROM.
         */
-       char s[MAN_MAC_ADDR_LENGTH + 1];
+
+#if MAN_MAC_ADDR_LENGTH % 2 != 0
+#error MAN_MAC_ADDR_LENGTH must be an even number
+#endif
+
+       char s[(3 * MAN_MAC_ADDR_LENGTH) / 2];
+       char *src;
+       char *dst;
 
        if (0 != getenv("ethaddr") && 0 != getenv("eth1addr"))
                return;
 
-       if (0 == man_data_read_field(s, MAN_MAC_ADDR_FIELD,
-                                    MAN_MAC_ADDR_LENGTH))
+       if (0 == man_data_read_field(s + (MAN_MAC_ADDR_LENGTH / 2) - 1,
+                                    MAN_MAC_ADDR_FIELD, MAN_MAC_ADDR_LENGTH))
                return;
 
+       for (src = s + (MAN_MAC_ADDR_LENGTH / 2) - 1, dst = s; src != dst;) {
+               *dst++ = *src++;
+               *dst++ = *src++;
+               *dst++ = ':';
+       }
        if (0 == getenv("ethaddr"))
                setenv("ethaddr", s);
 
        if (0 == getenv("eth1addr")) {
-               ++s[MAN_MAC_ADDR_LENGTH - 1];
+               ++s[((3 * MAN_MAC_ADDR_LENGTH) / 2) - 2];
                setenv("eth1addr", s);
        }
 }
 
 int misc_init_r(void)
 {
-       uint pbcr;
-       int size_val = 0;
-       u32 reg;
+       uint32_t pbcr;
+       int size_val;
+       uint32_t reg;
        unsigned long usb2d0cr = 0;
        unsigned long usb2phy0cr, usb2h0cr = 0;
        unsigned long sdr0_pfc1;
-       char *act = getenv("usbact");
-
-       /* Re-do flash sizing to get full correct info */
+       uint32_t const flash1_size = gd->bd->bi_flashsize - CFG_FLASH0_SIZE;
+       char const *const act = getenv("usbact");
 
-       /* adjust flash start and offset */
-       gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
+       /*
+        * Re-do FLASH1 sizing and adjust flash start and offset.
+        */
+       gd->bd->bi_flashstart = CFG_FLASH1_TOP - flash1_size;
        gd->bd->bi_flashoffset = 0;
 
-       mtdcr(ebccfga, pb0cr);
+       mtdcr(ebccfga, pb1cr);
        pbcr = mfdcr(ebccfgd);
-       size_val = ffs(gd->bd->bi_flashsize) - 21;
+       size_val = ffs(flash1_size) - 21;
        pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
-       mtdcr(ebccfga, pb0cr);
+       mtdcr(ebccfga, pb1cr);
        mtdcr(ebccfgd, pbcr);
 
        /*
@@ -250,14 +367,37 @@ int misc_init_r(void)
         */
        flash_get_size(gd->bd->bi_flashstart, 0);
 
-       /* Monitor protection ON by default */
-       (void)flash_protect(FLAG_PROTECT_SET, -CFG_MONITOR_LEN, 0xffffffff,
-                           &flash_info[0]);
+       /*
+        * Re-do FLASH1 sizing and adjust flash offset to reserve space for
+        * environment
+        */
+       gd->bd->bi_flashoffset =
+               CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - CFG_FLASH1_ADDR;
 
+       mtdcr(ebccfga, pb1cr);
+       pbcr = mfdcr(ebccfgd);
+       size_val = ffs(gd->bd->bi_flashsize - CFG_FLASH0_SIZE) - 21;
+       pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
+       mtdcr(ebccfga, pb1cr);
+       mtdcr(ebccfgd, pbcr);
+
+       /* Monitor protection ON by default */
+#if defined(CONFIG_KORAT_PERMANENT)
+       (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
+                           CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
+                           flash_info + 1);
+#else
+       (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
+                           CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1,
+                           flash_info);
+#endif
        /* Env protection ON by default */
+       (void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR,
+                           CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
+                           flash_info);
        (void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR_REDUND,
-                           CFG_ENV_ADDR_REDUND + 2 * CFG_ENV_SECT_SIZE - 1,
-                           &flash_info[0]);
+                           CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1,
+                           flash_info);
 
        /*
         * USB suff...
@@ -393,6 +533,8 @@ int misc_init_r(void)
 
        set_serial_number();
        set_mac_addresses();
+       gpio_write_bit(CFG_GPIO_ATMEGA_RESET_, 1);
+
        return 0;
 }
 
@@ -402,10 +544,10 @@ int checkboard(void)
        u8 const rev = in_8((u8 *) CFG_CPLD_BASE + 0);
 
        printf("Board: Korat, Rev. %X", rev);
-       if (s != NULL)
+       if (s)
                printf(", serial# %s", s);
 
-       printf(", Ethernet PHY 0: ");
+       printf(".\n       Ethernet PHY 0: ");
        if (gpio_read_out_bit(CFG_GPIO_PHY0_FIBER_SEL))
                printf("fiber");
        else
@@ -418,7 +560,10 @@ int checkboard(void)
                printf("copper");
 
        printf(".\n");
-       return (0);
+#if defined(CONFIG_KORAT_PERMANENT)
+       printf("       Executing permanent copy of U-Boot.\n");
+#endif
+       return 0;
 }
 
 #if defined(CFG_DRAM_TEST)
@@ -529,23 +674,26 @@ void pci_target_init(struct pci_controller *hose)
        /*
         * PowerPC440EPX PCI Master configuration.
         * Map one 1Gig range of PLB/processor addresses to PCI memory space.
-        * PLB address 0xA0000000-0xDFFFFFFF
-        *     ==> PCI address 0xA0000000-0xDFFFFFFF
+        * PLB address 0x80000000-0xBFFFFFFF
+        *     ==> PCI address 0x80000000-0xBFFFFFFF
         * Use byte reversed out routines to handle endianess.
         * Make this region non-prefetchable.
         */
        out32r(PCIX0_PMM0MA, 0x00000000);       /* PMM0 Mask/Attribute */
                                                /* - disabled b4 setting */
        out32r(PCIX0_PMM0LA, CFG_PCI_MEMBASE);  /* PMM0 Local Address */
-       out32r(PCIX0_PMM0PCILA, CFG_PCI_MEMBASE); /* PMM0 PCI Low Address */
+       out32r(PCIX0_PMM0PCILA,
+              CFG_PCI_MEMBASE);                /* PMM0 PCI Low Address */
        out32r(PCIX0_PMM0PCIHA, 0x00000000);    /* PMM0 PCI High Address */
        out32r(PCIX0_PMM0MA, 0xE0000001);       /* 512M + No prefetching, */
                                                /* and enable region */
 
        out32r(PCIX0_PMM1MA, 0x00000000);       /* PMM0 Mask/Attribute */
                                                /* - disabled b4 setting */
-       out32r(PCIX0_PMM1LA, CFG_PCI_MEMBASE2); /* PMM0 Local Address */
-       out32r(PCIX0_PMM1PCILA, CFG_PCI_MEMBASE2); /* PMM0 PCI Low Address */
+       out32r(PCIX0_PMM1LA,
+              CFG_PCI_MEMBASE + 0x20000000);   /* PMM0 Local Address */
+       out32r(PCIX0_PMM1PCILA,
+              CFG_PCI_MEMBASE + 0x20000000);   /* PMM0 PCI Low Address */
        out32r(PCIX0_PMM1PCIHA, 0x00000000);    /* PMM0 PCI High Address */
        out32r(PCIX0_PMM1MA, 0xE0000001);       /* 512M + No prefetching, */
                                                /* and enable region */
diff --git a/board/korat/u-boot-F7FC.lds b/board/korat/u-boot-F7FC.lds
new file mode 100644 (file)
index 0000000..cceb4f5
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  .resetvec 0xF7FBFFFC :
+  {
+    *(.resetvec)
+  } = 0xffff
+
+  .bootpg 0xF7FBF000 :
+  {
+    cpu/ppc4xx/start.o (.bootpg)
+  } = 0xffff
+
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    cpu/ppc4xx/start.o (.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  . = .;
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  . = .;
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss (NOLOAD)       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/doc/README.korat b/doc/README.korat
new file mode 100644 (file)
index 0000000..0a59f40
--- /dev/null
@@ -0,0 +1,51 @@
+The Korat board has two NOR flashes, FLASH0 and FLASH1, which are connected to
+chip select 0 and 1, respectively.  FLASH0 contains 16 MiB, and is mapped to
+addresses 0xFF000000 - 0xFFFFFFFF as U-Boot Flash Bank #2.  FLASH1 contains
+from 16 to 128 MiB, and is mapped to 0xF?000000 - 0xF7FFFFFF as U-Boot Flash
+Bank #1 (with the starting address depending on the flash size detected at
+runtime).  The write-enable pin on FLASH0 is disabled, so the contents of FLASH0
+cannot be modified in the field.  This also prevents FLASH0 from executing
+commands to return chip information, so its configuration is hard-coded in
+U-Boot.
+
+There are two versions of U-Boot for Korat: "permanent" and "upgradable".  The
+permanent U-Boot is pre-programmed at the top of FLASH0, e.g., at addresses
+0xFFFA0000 - 0xFFFFFFFF for the current 384 KiB size.  The upgradable U-Boot is
+located 256 KiB from the top of FLASH1, e.g. at addresses 0xF7F6000 - 0xF7FC0000
+for the current 384 KiB size.  FLASH1 addresses 0xF7FE0000 - 0xF7FF0000 are
+used for the U-Boot environmental parameters, and addresses 0xF7FC0000 -
+0xF7FDFFFF are used for the redundant copy of the parameters.  These locations
+are used by both versions of U-Boot.
+
+On booting, the permanent U-Boot in FLASH0 begins executing.  After performing
+minimal setup, it monitors the state of the board's Reset switch (GPIO47).  If
+the switch is sensed as open before a timeout period, then U-Boot branches to
+address 0xF7FBFFFC.  This causes the upgradable U-Boot to execute from the
+beginning.  If the switch remains closed thoughout the timeout period, the
+permanent U-Boot activates the on-board buzzer until the switch is sensed as
+opened.  It then continues to execute without branching to FLASH1.  The effect
+of this is that normally the Korat board boots its upgradable U-Boot, but, if
+this has been corrupted, the user can boot the permanent U-Boot, which can then
+be used to erase and reload FLASH1 as needed.
+
+Note that it is not necessary for the permanent U-Boot to have all the latest
+features, but only that it have sufficient functionality (working "tftp",
+"erase", "cp.b", etc.) to repair FLASH1.  Also, the permanent U-Boot makes no
+assumptions about the size of FLASH1 or the size of the upgradable U-Boot: it is
+sufficient that the upgradable U-Boot can be started by a branch to 0xF7FBFFFC.
+
+The build sequence:
+
+       make korat_config
+       make all perm=1
+
+builds the permanent U-Boot by selecting loader file "u-boot.lds" and defining
+preprocessor symbol "CONFIG_KORAT_PERMANENT".  The default build:
+
+       make korat_config
+       make all
+
+creates the upgradable U-Boot but selecting loader file "u-boot-F7FC.lds" and
+leaving preprocessor symbol "CONFIG_KORAT_PERMANENT" undefined.
+
+2008-02-22, Larry Johnson <lrj@acm.org>
index de672ea..48d73ac 100644 (file)
  * Manufacturer's information serial EEPROM parameters
  */
 #define MAN_DATA_EEPROM_ADDR   0x53    /* EEPROM I2C address           */
-#define MAN_SERIAL_NO_FIELD    2
-#define MAN_SERIAL_NO_LENGTH   13
+#define MAN_INFO_FIELD         2
+#define MAN_INFO_LENGTH                9
 #define MAN_MAC_ADDR_FIELD     3
-#define MAN_MAC_ADDR_LENGTH    17
+#define MAN_MAC_ADDR_LENGTH    12
 
 /*
  * Base addresses -- Note these are effective addresses where the actual
 #define CFG_MONITOR_LEN                (384 * 1024) /* Reserve 384 kiB for Monitor  */
 #define CFG_MALLOC_LEN         (256 * 1024) /* Reserve 256 kiB for malloc() */
 
-#define CFG_BOOT_BASE_ADDR     0xf0000000
 #define CFG_SDRAM_BASE         0x00000000      /* _must_ be 0          */
-#define CFG_FLASH_BASE         0xfc000000      /* start of FLASH       */
+#define CFG_FLASH0_SIZE                0x01000000
+#define CFG_FLASH0_ADDR                (-CFG_FLASH0_SIZE)
+#define CFG_FLASH1_TOP         0xF8000000
+#define CFG_FLASH1_MAX_SIZE    0x08000000
+#define CFG_FLASH1_ADDR                (CFG_FLASH1_TOP - CFG_FLASH1_MAX_SIZE)
+#define CFG_FLASH_BASE         CFG_FLASH1_ADDR /* start of FLASH       */
 #define CFG_MONITOR_BASE       TEXT_BASE
 #define CFG_OCM_BASE           0xe0010000      /* ocm                  */
 #define CFG_OCM_DATA_ADDR      CFG_OCM_BASE
 #define CFG_PCI_BASE           0xe0000000      /* Internal PCI regs    */
 #define CFG_PCI_MEMBASE                0x80000000      /* mapped pci memory    */
-#define CFG_PCI_MEMBASE1       CFG_PCI_MEMBASE  + 0x10000000
-#define CFG_PCI_MEMBASE2       CFG_PCI_MEMBASE1 + 0x10000000
-#define CFG_PCI_MEMBASE3       CFG_PCI_MEMBASE2 + 0x10000000
 
 /* Don't change either of these */
 #define CFG_PERIPHERAL_BASE    0xef600000      /* internal peripherals */
 /*
  * FLASH related
  */
-#define CFG_FLASH_CFI                  /* The flash is CFI compatible  */
-#define CFG_FLASH_CFI_DRIVER           /* Use common CFI driver        */
+#define CFG_FLASH_CFI                  /* The flash is CFI compatible        */
+#define CFG_FLASH_CFI_DRIVER           /* Use common CFI driver              */
+#define CONFIG_FLASH_CFI_LEGACY                /* Allow hard-coded config for FLASH0 */
 
-#define CFG_FLASH_BANKS_LIST   { CFG_FLASH_BASE }
+#define CFG_FLASH_BANKS_LIST   { CFG_FLASH1_ADDR, CFG_FLASH0_ADDR }
 
-#define CFG_MAX_FLASH_BANKS    1       /* max number of memory banks         */
-#define CFG_MAX_FLASH_SECT     512     /* max number of sectors on one chip  */
+#define CFG_MAX_FLASH_BANKS    2       /* max number of memory banks         */
+#define CFG_MAX_FLASH_SECT     1024    /* max number of sectors on one chip  */
 
 #define CFG_FLASH_ERASE_TOUT   120000  /* Timeout for Flash Erase (in ms)    */
 #define CFG_FLASH_WRITE_TOUT   500     /* Timeout for Flash Write (in ms)    */
 #define CFG_FLASH_QUIET_TEST   1       /* don't warn upon unknown flash      */
 
 #define CFG_ENV_SECT_SIZE      0x20000 /* size of one complete sector        */
-#define CFG_ENV_ADDR           ((-CFG_MONITOR_LEN)-CFG_ENV_SECT_SIZE)
+#define CFG_ENV_ADDR           (CFG_FLASH1_TOP - CFG_ENV_SECT_SIZE)
 #define        CFG_ENV_SIZE            0x2000  /* Total Size of Environment Sector   */
 
-/* Address and size of Redundant Environment Sector    */
-#define CFG_ENV_ADDR_REDUND    (CFG_ENV_ADDR-CFG_ENV_SECT_SIZE)
-#define CFG_ENV_SIZE_REDUND    (CFG_ENV_SIZE)
+/* Address and size of Redundant Environment Sector */
+#define CFG_ENV_ADDR_REDUND    (CFG_ENV_ADDR - CFG_ENV_SECT_SIZE)
+#define CFG_ENV_SIZE_REDUND    CFG_ENV_SIZE
 
 /*
  * DDR SDRAM
 #define CFG_BOOTFILE           "bootfile=/tftpboot/korat/uImage\0"
 #define CFG_ROOTPATH           "rootpath=/opt/eldk/ppc_4xxFP\0"
 
+/* Note: kernel_addr and ramdisk_addr assume that FLASH1 is 64 MiB. */
 #define        CONFIG_EXTRA_ENV_SETTINGS                                       \
        CFG_BOOTFILE                                                    \
        CFG_ROOTPATH                                                    \
                "bootm ${kernel_addr} ${ramdisk_addr}\0"                \
        "net_nfs=tftp 200000 ${bootfile};run nfsargs addip addtty;"     \
                "bootm\0"                                               \
-       "kernel_addr=FC000000\0"                                        \
-       "ramdisk_addr=FC180000\0"                                       \
+       "kernel_addr=F4000000\0"                                        \
+       "ramdisk_addr=F4400000\0"                                       \
        "load=tftp 200000 /tftpboot/${hostname}/u-boot.bin\0"           \
        "update=protect off FFFA0000 FFFFFFFF;era FFFA0000 FFFFFFFF;"   \
                "cp.b 200000 FFFA0000 60000\0"                          \
 #define CONFIG_PHY_ADDR                2       /* PHY address, See schematics  */
 #define CONFIG_PHY_DYNAMIC_ANEG        1
 
-#define CONFIG_PHY_RESET       1       /* reset phy upon startup       */
+#undef CONFIG_PHY_RESET                        /* Don't do software PHY reset  */
 #define CONFIG_PHY_GIGE                1       /* Include GbE speed/duplex detection */
 
 #define CONFIG_HAS_ETH0
 #define CONFIG_VERSION_VARIABLE 1      /* include version env variable */
 
 /*
+ * Korat-specific options
+ */
+#define CFG_KORAT_MAN_RESET_MS 10000   /* timeout for manufacturer reset */
+
+/*
  * PCI stuff
  */
 /* General PCI */
  */
 
 /* Memory Bank 0 (NOR-FLASH) initialization                            */
+#if CFG_FLASH0_SIZE == 0x01000000
+#define CFG_EBC_PB0AP          0x04017300
+#define CFG_EBC_PB0CR          (CFG_FLASH0_ADDR | 0x0009A000)
+#elif CFG_FLASH0_SIZE == 0x04000000
 #define CFG_EBC_PB0AP          0x04017300
-#define CFG_EBC_PB0CR          (CFG_FLASH_BASE | 0x000DA000)
+#define CFG_EBC_PB0CR          (CFG_FLASH0_ADDR | 0x000DA000)
+#else
+#error Unable to configure chip select for current CFG_FLASH0_SIZE
+#endif
 
 /* Memory Bank 1 (NOR-FLASH) initialization                            */
+#if CFG_FLASH1_MAX_SIZE == 0x08000000
 #define CFG_EBC_PB1AP          0x04017300
-#define CFG_EBC_PB1CR          (0xF8000000 | 0x000DA000)
+#define CFG_EBC_PB1CR          (CFG_FLASH1_ADDR | 0x000FA000)
+#else
+#error Unable to configure chip select for current CFG_FLASH1_MAX_SIZE
+#endif
 
 /* Memory Bank 2 (CPLD) initialization                                 */
 #define CFG_EBC_PB2AP          0x04017300
  * GPIO63  xxxx   x    x   (reserved for trace port)
  */
 
+#define CFG_GPIO_ATMEGA_RESET_ 12
 #define CFG_GPIO_ATMEGA_SS_    13
 #define CFG_GPIO_PHY0_FIBER_SEL        27
 #define CFG_GPIO_PHY1_FIBER_SEL        28
 #define CFG_GPIO_SFP1_TX_EN_   33
 #define CFG_GPIO_PHY0_EN       45
 #define CFG_GPIO_PHY1_EN       46
+#define CFG_GPIO_RESET_PRESSED_        47
 
 /*
  * PPC440 GPIO Configuration