]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - lib_ppc/board.c
* Patches by Yuli Barcohen, 13 Jul 2003:
[people/ms/u-boot.git] / lib_ppc / board.c
index bfc494ef8e24578e21242f3dd9a0afd21e1edd54..108244e296a96ade4c1cbf0cae8b5a2303ded53b 100644 (file)
@@ -30,6 +30,9 @@
 #ifdef CONFIG_8xx
 #include <mpc8xx.h>
 #endif
+#ifdef CONFIG_5xx
+#include <mpc5xx.h>
+#endif
 #if (CONFIG_COMMANDS & CFG_CMD_IDE)
 #include <ide.h>
 #endif
 #include <status_led.h>
 #endif
 #include <net.h>
-#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
-#include <cmd_bedbug.h>
-#endif
 #ifdef CFG_ALLOC_DPRAM
+#if !defined(CONFIG_8260)
 #include <commproc.h>
 #endif
+#endif
 #include <version.h>
 #if defined(CONFIG_BAB7xx)
 #include <w83c553f.h>
@@ -68,6 +70,9 @@ void doc_init (void);
     defined(CONFIG_SOFT_I2C)
 #include <i2c.h>
 #endif
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+void nand_init (void);
+#endif
 
 static char *failed = "*** failed ***\n";
 
@@ -85,6 +90,14 @@ extern flash_info_t flash_info[];
 #define        TOTAL_MALLOC_LEN        CFG_MALLOC_LEN
 #endif
 
+extern ulong __init_end;
+extern ulong _end;
+ulong monitor_flash_len;
+
+#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+#include <bedbug/type.h>
+#endif
+
 /*
  * Begin and End of memory area for malloc(), and current "brk"
  */
@@ -149,6 +162,8 @@ static void syscalls_init (void)
 
        syscall_tbl[SYSCALL_INSTALL_HDLR] = (void *) irq_install_handler;
        syscall_tbl[SYSCALL_FREE_HDLR] = (void *) irq_free_handler;
+       syscall_tbl[SYSCALL_GET_TIMER] = (void *)get_timer;
+       syscall_tbl[SYSCALL_UDELAY] = (void *)udelay;
 
        addr = (ulong *) 0xc00;         /* syscall ISR addr */
 
@@ -158,7 +173,15 @@ static void syscalls_init (void)
        *addr++ |= NR_SYSCALLS >> 16;
        *addr++ |= NR_SYSCALLS & 0xFFFF;
 
+#ifndef CONFIG_5XX
        flush_cache (0x0C00, 0x10);
+#endif
+       /* Initialize syscalls stack pointer                                 */
+       addr = (ulong *) 0xCFC;
+       *addr = (ulong)addr;
+#ifndef CONFIG_5xx
+       flush_cache ((ulong)addr, 0x10);
+#endif
 }
 
 /*
@@ -192,7 +215,6 @@ static int init_baudrate (void)
        gd->baudrate = (i > 0)
                        ? (int) simple_strtoul (tmp, NULL, 10)
                        : CONFIG_BAUDRATE;
-
        return (0);
 }
 
@@ -265,8 +287,10 @@ init_fnc_t *init_sequence[] = {
        get_clocks,             /* get CPU and bus clocks (etc.) */
        init_timebase,
 #ifdef CFG_ALLOC_DPRAM
+#if !defined(CONFIG_8260)
        dpram_init,
 #endif
+#endif
 #if defined(CONFIG_BOARD_POSTCLK_INIT)
        board_postclk_init,
 #endif
@@ -295,6 +319,9 @@ init_fnc_t *init_sequence[] = {
 #endif
 #if defined(CONFIG_DTT)                /* Digital Thermometers and Thermostats */
        dtt_init,
+#endif
+#ifdef CONFIG_POST
+       post_init_f,
 #endif
        INIT_FUNC_WATCHDOG_RESET
        init_func_ram,
@@ -355,21 +382,13 @@ void board_init_f (ulong bootflag)
         * relocate the code and continue running from DRAM.
         *
         * Reserve memory at end of RAM for (top down in that order):
+        *  - kernel log buffer
         *  - protected RAM
         *  - LCD framebuffer
         *  - monitor code
         *  - board info struct
         */
-       len = get_endaddr () - CFG_MONITOR_BASE;
-
-       if (len > CFG_MONITOR_LEN) {
-               printf ("*** U-Boot size %ld > reserved memory (%d)\n",
-                               len, CFG_MONITOR_LEN);
-               hang ();
-       }
-
-       if (CFG_MONITOR_LEN > len)
-               len = CFG_MONITOR_LEN;
+       len = (ulong)&_end - CFG_MONITOR_BASE;
 
 #ifndef        CONFIG_VERY_BIG_RAM
        addr = CFG_SDRAM_BASE + gd->ram_size;
@@ -379,6 +398,12 @@ void board_init_f (ulong bootflag)
               (gd->ram_size > 256 << 20) ? 256 << 20 : gd->ram_size;
 #endif
 
+#ifdef CONFIG_LOGBUFFER
+       /* reserve kernel log buffer */
+       addr -= (LOGBUFF_RESERVE);
+       debug ("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr);
+#endif
+
 #ifdef CONFIG_PRAM
        /*
         * reserve protected RAM
@@ -386,16 +411,12 @@ void board_init_f (ulong bootflag)
        i = getenv_r ("pram", tmp, sizeof (tmp));
        reg = (i > 0) ? simple_strtoul (tmp, NULL, 10) : CONFIG_PRAM;
        addr -= (reg << 10);            /* size is in kB */
-# ifdef DEBUG
-       printf ("Reserving %ldk for protected RAM at %08lx\n", reg, addr);
-# endif
+       debug ("Reserving %ldk for protected RAM at %08lx\n", reg, addr);
 #endif /* CONFIG_PRAM */
 
        /* round down to next 4 kB limit */
        addr &= ~(4096 - 1);
-#ifdef DEBUG
-       printf ("Top of RAM usable for U-Boot at: %08lx\n", addr);
-#endif
+       debug ("Top of RAM usable for U-Boot at: %08lx\n", addr);
 
 #ifdef CONFIG_LCD
        /* reserve memory for LCD display (always full pages) */
@@ -416,18 +437,18 @@ void board_init_f (ulong bootflag)
        addr -= len;
        addr &= ~(4096 - 1);
 
-#ifdef DEBUG
-       printf ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
+       debug ("Reserving %ldk for U-Boot at: %08lx\n", len >> 10, addr);
+
+#ifdef CONFIG_AMIGAONEG3SE
+       gd->relocaddr = addr;
 #endif
 
        /*
         * reserve memory for malloc() arena
         */
        addr_sp = addr - TOTAL_MALLOC_LEN;
-#ifdef DEBUG
-       printf ("Reserving %dk for malloc() at: %08lx\n",
+       debug ("Reserving %dk for malloc() at: %08lx\n",
                        TOTAL_MALLOC_LEN >> 10, addr_sp);
-#endif
 
        /*
         * (permanently) allocate a Board Info struct
@@ -436,16 +457,12 @@ void board_init_f (ulong bootflag)
        addr_sp -= sizeof (bd_t);
        bd = (bd_t *) addr_sp;
        gd->bd = bd;
-#ifdef DEBUG
-       printf ("Reserving %d Bytes for Board Info at: %08lx\n",
+       debug ("Reserving %d Bytes for Board Info at: %08lx\n",
                        sizeof (bd_t), addr_sp);
-#endif
        addr_sp -= sizeof (gd_t);
        id = (gd_t *) addr_sp;
-#ifdef DEBUG
-       printf ("Reserving %d Bytes for Global Data at: %08lx\n",
+       debug ("Reserving %d Bytes for Global Data at: %08lx\n",
                        sizeof (gd_t), addr_sp);
-#endif
 
        /*
         * Finally, we set up a new (bigger) stack.
@@ -457,9 +474,7 @@ void board_init_f (ulong bootflag)
        addr_sp &= ~0xF;
        *((ulong *) addr_sp)-- = 0;
        *((ulong *) addr_sp)-- = 0;
-#ifdef DEBUG
-       printf ("Stack Pointer at: %08lx\n", addr_sp);
-#endif
+       debug ("Stack Pointer at: %08lx\n", addr_sp);
 
        /*
         * Save local variables to board info struct
@@ -476,7 +491,7 @@ void board_init_f (ulong bootflag)
        bd->bi_sramsize  = 0;           /* FIXME */ /* size  of  SRAM memory      */
 #endif
 
-#if defined(CONFIG_8xx) || defined(CONFIG_8260)
+#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx)
        bd->bi_immr_base = CFG_IMMR;    /* base  of IMMR register     */
 #endif
 
@@ -500,20 +515,21 @@ void board_init_f (ulong bootflag)
 
        bd->bi_procfreq = gd->cpu_clk;  /* Processor Speed, In Hz */
        bd->bi_plb_busfreq = gd->bus_clk;
-#ifdef CONFIG_405GP
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
        bd->bi_pci_busfreq = get_PCI_freq ();
 #endif
 #endif
 
-#ifdef DEBUG
-       printf ("New Stack Pointer is: %08lx\n", addr_sp);
-#endif
+       debug ("New Stack Pointer is: %08lx\n", addr_sp);
 
        WATCHDOG_RESET ();
 
 #ifdef CONFIG_POST
        post_bootmode_init();
-       post_run (NULL, POST_ROM | post_bootmode_get(0));
+       if (post_hotkeys_pressed(gd)) /* Force the long-running tests (memory) */
+               post_run (NULL, POST_ROM | POST_SLOWTEST);
+       else
+               post_run (NULL, POST_ROM | post_bootmode_get(0));
 #endif
 
        WATCHDOG_RESET();
@@ -539,7 +555,6 @@ void board_init_f (ulong bootflag)
 void board_init_r (gd_t *id, ulong dest_addr)
 {
        DECLARE_GLOBAL_DATA_PTR;
-
        cmd_tbl_t *cmdtp;
        char *s, *e;
        bd_t *bd;
@@ -558,20 +573,19 @@ void board_init_r (gd_t *id, ulong dest_addr)
 
        gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
 
-#ifdef DEBUG
-       printf ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
-#endif
+       debug ("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
 
        WATCHDOG_RESET ();
 
        gd->reloc_off = dest_addr - CFG_MONITOR_BASE;
 
+       monitor_flash_len = (ulong)&__init_end - dest_addr;
+
        /*
         * We have to relocate the command table manually
         */
-       for (cmdtp = &cmd_tbl[0]; cmdtp->name; cmdtp++) {
+       for (cmdtp = &__u_boot_cmd_start; cmdtp !=  &__u_boot_cmd_end; cmdtp++) {
                ulong addr;
-
                addr = (ulong) (cmdtp->cmd) + gd->reloc_off;
 #if 0
                printf ("Command \"%s\": 0x%08lx => 0x%08lx\n",
@@ -602,9 +616,10 @@ void board_init_r (gd_t *id, ulong dest_addr)
        WATCHDOG_RESET ();
 
 #ifdef CONFIG_LOGBUFFER
-       logbuff_reset ();
+       logbuff_init_ptrs ();
 #endif
 #ifdef CONFIG_POST
+       post_output_backlog ();
        post_reloc ();
 #endif
 
@@ -614,12 +629,15 @@ void board_init_r (gd_t *id, ulong dest_addr)
        icache_enable ();       /* it's time to enable the instruction cache */
 #endif
 
-#if defined(CONFIG_BAB7xx)
+#if defined(CONFIG_BAB7xx) || defined(CONFIG_CPC45)
        /*
-        * Do pci configuration on BAB 7xx _before_ the flash
-        * is initialised, because we need the ISA bridge there.
+        * Do PCI configuration on BAB7xx and CPC45 _before_ the flash
+        * gets initialised, because we need the ISA resp. PCI_to_LOCAL bus
+        * bridge there.
         */
        pci_init ();
+#endif
+#if defined(CONFIG_BAB7xx)
        /*
         * Initialise the ISA bridge
         */
@@ -666,7 +684,7 @@ void board_init_r (gd_t *id, ulong dest_addr)
 #if defined(CONFIG_PCU_E) || defined(CONFIG_OXC)
        bd->bi_flashoffset = 0;
 #elif CFG_MONITOR_BASE == CFG_FLASH_BASE
-       bd->bi_flashoffset = CFG_MONITOR_LEN;   /* reserved area for startup monitor  */
+       bd->bi_flashoffset = monitor_flash_len; /* reserved area for startup monitor  */
 #else
        bd->bi_flashoffset = 0;
 #endif
@@ -700,10 +718,10 @@ void board_init_r (gd_t *id, ulong dest_addr)
 
        /*
         * 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.
+        * 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)
@@ -783,7 +801,6 @@ void board_init_r (gd_t *id, ulong dest_addr)
     defined(CONFIG_COGENT)     || \
     defined(CONFIG_CPCI405)    || \
     defined(CONFIG_EVB64260)   || \
-    defined(CONFIG_HYMOD)      || \
     defined(CONFIG_KUP4K)      || \
     defined(CONFIG_LWMON)      || \
     defined(CONFIG_PCU_E)      || \
@@ -800,20 +817,20 @@ void board_init_r (gd_t *id, ulong dest_addr)
 
 #if (CONFIG_COMMANDS & CFG_CMD_NET) && ( \
     defined(CONFIG_CCM)                || \
+    defined(CONFIG_ELPT860)    || \
     defined(CONFIG_EP8260)     || \
     defined(CONFIG_IP860)      || \
     defined(CONFIG_IVML24)     || \
     defined(CONFIG_IVMS8)      || \
     defined(CONFIG_LWMON)      || \
     defined(CONFIG_MPC8260ADS) || \
+    defined(CONFIG_MPC8266ADS) || \
     defined(CONFIG_PCU_E)      || \
     defined(CONFIG_RPXSUPER)   || \
     defined(CONFIG_SPD823TS)   )
 
        WATCHDOG_RESET ();
-# ifdef DEBUG
-       puts ("Reset Ethernet PHY\n");
-# endif
+       debug ("Reset Ethernet PHY\n");
        reset_phy ();
 #endif
 
@@ -823,9 +840,7 @@ void board_init_r (gd_t *id, ulong dest_addr)
        kgdb_init ();
 #endif
 
-#ifdef DEBUG
-       printf ("U-Boot relocated to %08lx\n", dest_addr);
-#endif
+       debug ("U-Boot relocated to %08lx\n", dest_addr);
 
        /*
         * Enable Interrupts
@@ -873,6 +888,11 @@ void board_init_r (gd_t *id, ulong dest_addr)
        doc_init ();
 #endif
 
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+       WATCHDOG_RESET ();
+       nand_init();            /* go init the NAND */
+#endif
+
 #if (CONFIG_COMMANDS & CFG_CMD_NET) && defined(CONFIG_NET_MULTI)
        WATCHDOG_RESET ();
        puts ("Net:   ");
@@ -880,8 +900,11 @@ void board_init_r (gd_t *id, ulong dest_addr)
 #endif
 
 #ifdef CONFIG_POST
-       post_run (NULL, POST_RAM | post_bootmode_get(0));
-       if (post_bootmode_get(0) & POST_POWERFAIL) {
+       if (gd->post_hotkeys_latch)
+               post_run (NULL, POST_RAM | POST_SLOWTEST);
+       else
+               post_run (NULL, POST_RAM | post_bootmode_get(0));
+       if (post_bootmode_get(0) & POST_SLOWTEST) {
                post_bootmode_clear();
                board_poweroff();
        }
@@ -918,26 +941,41 @@ void board_init_r (gd_t *id, ulong dest_addr)
        bedbug_init ();
 #endif
 
-#ifdef CONFIG_PRAM
+#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
        /*
         * Export available size of memory for Linux,
         * taking into account the protected RAM at top of memory
         */
        {
                ulong pram;
-               char *s;
                uchar memsz[32];
+#ifdef CONFIG_PRAM
+               char *s;
 
                if ((s = getenv ("pram")) != NULL) {
                        pram = simple_strtoul (s, NULL, 10);
                } else {
                        pram = CONFIG_PRAM;
                }
+#else
+               pram=0;
+#endif
+#ifdef CONFIG_LOGBUFFER
+               /* Also take the logbuffer into account (pram is in kB) */
+               pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024;
+#endif
                sprintf (memsz, "%ldk", (bd->bi_memsize / 1024) - pram);
                setenv ("mem", memsz);
        }
 #endif
 
+#ifdef CONFIG_MODEM_SUPPORT
+ {
+        extern int do_mdm_init;
+        do_mdm_init = gd->do_mdm_init;
+ }
+#endif
+
        /* Initialization complete - start the monitor */
 
        /* main_loop() can return to retry autoboot, if so just run it again. */
@@ -955,6 +993,104 @@ void hang (void)
        for (;;);
 }
 
+#ifdef CONFIG_MODEM_SUPPORT
+/* called from main loop (common/main.c) */
+extern void  dbg(const char *fmt, ...);
+int mdm_init (void)
+{
+       char env_str[16];
+       char *init_str;
+       int i;
+       extern char console_buffer[];
+       static inline void mdm_readline(char *buf, int bufsiz);
+       extern void enable_putc(void);
+       extern int hwflow_onoff(int);
+
+       enable_putc(); /* enable serial_putc() */
+
+#ifdef CONFIG_HWFLOW
+       init_str = getenv("mdm_flow_control");
+       if (init_str && (strcmp(init_str, "rts/cts") == 0))
+               hwflow_onoff (1);
+       else
+               hwflow_onoff(-1);
+#endif
+
+       for (i = 1;;i++) {
+               sprintf(env_str, "mdm_init%d", i);
+               if ((init_str = getenv(env_str)) != NULL) {
+                       serial_puts(init_str);
+                       serial_puts("\n");
+                       for(;;) {
+                               mdm_readline(console_buffer, CFG_CBSIZE);
+                               dbg("ini%d: [%s]", i, console_buffer);
+
+                               if ((strcmp(console_buffer, "OK") == 0) ||
+                                       (strcmp(console_buffer, "ERROR") == 0)) {
+                                       dbg("ini%d: cmd done", i);
+                                       break;
+                               } else /* in case we are originating call ... */
+                                       if (strncmp(console_buffer, "CONNECT", 7) == 0) {
+                                               dbg("ini%d: connect", i);
+                                               return 0;
+                                       }
+                       }
+               } else
+                       break; /* no init string - stop modem init */
+
+               udelay(100000);
+       }
+
+       udelay(100000);
+
+       /* final stage - wait for connect */
+       for(;i > 1;) { /* if 'i' > 1 - wait for connection
+                                 message from modem */
+               mdm_readline(console_buffer, CFG_CBSIZE);
+               dbg("ini_f: [%s]", console_buffer);
+               if (strncmp(console_buffer, "CONNECT", 7) == 0) {
+                       dbg("ini_f: connected");
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+/* 'inline' - We have to do it fast */
+static inline void mdm_readline(char *buf, int bufsiz)
+{
+       char c;
+       char *p;
+       int n;
+
+       n = 0;
+       p = buf;
+       for(;;) {
+               c = serial_getc();
+
+               /*              dbg("(%c)", c); */
+
+               switch(c) {
+               case '\r':
+                       break;
+               case '\n':
+                       *p = '\0';
+                       return;
+
+               default:
+                       if(n++ > bufsiz) {
+                               *p = '\0';
+                               return; /* sanity check */
+                       }
+                       *p = c;
+                       p++;
+                       break;
+               }
+       }
+}
+#endif
+
 #if 0 /* We could use plain global data, but the resulting code is bigger */
 /*
  * Pointer to initial global data area