uboot/arch/sparc/lib/board.c
<<
>>
Prefs
   1/* SPARC Board initialization
   2 *
   3 * (C) Copyright 2000-2006
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 *
   6 * (C) Copyright 2007
   7 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
   8 *
   9 * See file CREDITS for list of people who contributed to this
  10 * project.
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation; either version 2 of
  15 * the License, or (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25 * MA 02111-1307 USA
  26 */
  27
  28#include <common.h>
  29#include <command.h>
  30#include <malloc.h>
  31#include <stdio_dev.h>
  32#include <config.h>
  33#if defined(CONFIG_CMD_IDE)
  34#include <ide.h>
  35#endif
  36#ifdef CONFIG_STATUS_LED
  37#include <status_led.h>
  38#endif
  39#include <net.h>
  40#include <serial.h>
  41#include <version.h>
  42#if defined(CONFIG_POST)
  43#include <post.h>
  44#endif
  45#ifdef CONFIG_PS2KBD
  46#include <keyboard.h>
  47#endif
  48#ifdef CONFIG_CMD_AMBAPP
  49#include <ambapp.h>
  50#endif
  51
  52#ifdef CONFIG_BITBANGMII
  53#include <miiphy.h>
  54#endif
  55
  56DECLARE_GLOBAL_DATA_PTR;
  57
  58/* Debug options
  59#define DEBUG_INIT_SEQUENCE
  60#define DEBUG_MEM_LAYOUT
  61#define DEBUG_COMMANDS
  62*/
  63
  64extern void timer_interrupt_init(void);
  65extern void malloc_bin_reloc(void);
  66extern int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]);
  67extern int prom_init(void);
  68
  69#if defined(CONFIG__CMD_DOC)
  70void doc_init(void);
  71#endif
  72
  73#if !defined(CONFIG_SYS_NO_FLASH)
  74static char *failed = "*** failed ***\n";
  75#endif
  76
  77#include <environment.h>
  78
  79ulong monitor_flash_len;
  80
  81/************************************************************************
  82 * Init Utilities                                                       *
  83 ************************************************************************
  84 * Some of this code should be moved into the core functions,
  85 * but let's get it working (again) first...
  86 */
  87
  88static int init_baudrate(void)
  89{
  90        gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
  91        return 0;
  92}
  93
  94/***********************************************************************/
  95
  96/*
  97 * All attempts to come up with a "common" initialization sequence
  98 * that works for all boards and architectures failed: some of the
  99 * requirements are just _too_ different. To get rid of the resulting
 100 * mess of board dependend #ifdef'ed code we now make the whole
 101 * initialization sequence configurable to the user.
 102 *
 103 * The requirements for any new initalization function is simple: it
 104 * receives a pointer to the "global data" structure as it's only
 105 * argument, and returns an integer return code, where 0 means
 106 * "continue" and != 0 means "fatal error, hang the system".
 107 */
 108typedef int (init_fnc_t) (void);
 109
 110#define WATCHDOG_RESET(x)
 111
 112/************************************************************************
 113 * Initialization sequence                                              *
 114 ************************************************************************
 115 */
 116
 117init_fnc_t *init_sequence[] = {
 118
 119#if defined(CONFIG_BOARD_EARLY_INIT_F)
 120        board_early_init_f,
 121#endif
 122        serial_init,
 123
 124        init_timebase,
 125
 126#if defined(CONFIG_CMD_AMBAPP)
 127        ambapp_init_reloc,
 128#endif
 129
 130        env_init,
 131
 132        init_baudrate,
 133
 134        console_init_f,
 135        display_options,
 136
 137        checkcpu,
 138        checkboard,
 139#if defined(CONFIG_MISC_INIT_F)
 140        misc_init_f,
 141#endif
 142
 143#ifdef CONFIG_POST
 144        post_init_f,
 145#endif
 146
 147        NULL,                   /* Terminate this list,
 148                                 * beware: this list will be relocated
 149                                 * which means that NULL will become
 150                                 * NULL+RELOC_OFFSET. We simply make
 151                                 * NULL be -RELOC_OFFSET instead.
 152                                 */
 153};
 154
 155/************************************************************************
 156 *
 157 * This is the SPARC board initialization routine, running from RAM.
 158 *
 159 ************************************************************************
 160 */
 161#ifdef DEBUG_INIT_SEQUENCE
 162char *str_init_seq = "INIT_SEQ 00\n";
 163char *str_init_seq_done = "\n\rInit sequence done...\r\n\r\n";
 164#endif
 165
 166void board_init_f(ulong bootflag)
 167{
 168        bd_t *bd;
 169        unsigned char *s;
 170        init_fnc_t **init_fnc_ptr;
 171        int j;
 172
 173#ifndef CONFIG_SYS_NO_FLASH
 174        ulong flash_size;
 175#endif
 176
 177        gd = (gd_t *) (CONFIG_SYS_GBL_DATA_OFFSET);
 178
 179        /* Clear initial global data */
 180        memset((void *)gd, 0, sizeof(gd_t));
 181
 182        gd->bd = (bd_t *) (gd + 1);     /* At end of global data */
 183        gd->baudrate = CONFIG_BAUDRATE;
 184        gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
 185
 186        bd = gd->bd;
 187        bd->bi_memstart = CONFIG_SYS_RAM_BASE;
 188        bd->bi_memsize = CONFIG_SYS_RAM_SIZE;
 189        bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 190#if     defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE)
 191        bd->bi_sramstart = CONFIG_SYS_SRAM_BASE;
 192        bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;
 193#endif
 194        bd->bi_baudrate = CONFIG_BAUDRATE;
 195        bd->bi_bootflags = bootflag;    /* boot / reboot flag (for LynxOS)    */
 196
 197        gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
 198        gd->reloc_off = CONFIG_SYS_RELOC_MONITOR_BASE - CONFIG_SYS_MONITOR_BASE;
 199
 200        for (init_fnc_ptr = init_sequence, j = 0; *init_fnc_ptr;
 201             ++init_fnc_ptr, j++) {
 202#ifdef DEBUG_INIT_SEQUENCE
 203                if (j > 9)
 204                        str_init_seq[9] = '0' + (j / 10);
 205                str_init_seq[10] = '0' + (j - (j / 10) * 10);
 206                serial_puts(str_init_seq);
 207#endif
 208                if ((*init_fnc_ptr + gd->reloc_off) () != 0) {
 209                        hang();
 210                }
 211        }
 212#ifdef DEBUG_INIT_SEQUENCE
 213        serial_puts(str_init_seq_done);
 214#endif
 215
 216        /*
 217         * Now that we have DRAM mapped and working, we can
 218         * relocate the code and continue running from DRAM.
 219         *
 220         * Reserve memory at end of RAM for (top down in that order):
 221         *  - kernel log buffer
 222         *  - protected RAM
 223         *  - LCD framebuffer
 224         *  - monitor code
 225         *  - board info struct
 226         */
 227#ifdef DEBUG_MEM_LAYOUT
 228        printf("CONFIG_SYS_MONITOR_BASE:       0x%lx\n", CONFIG_SYS_MONITOR_BASE);
 229        printf("CONFIG_ENV_ADDR:           0x%lx\n", CONFIG_ENV_ADDR);
 230        printf("CONFIG_SYS_RELOC_MONITOR_BASE: 0x%lx (%d)\n", CONFIG_SYS_RELOC_MONITOR_BASE,
 231               CONFIG_SYS_MONITOR_LEN);
 232        printf("CONFIG_SYS_MALLOC_BASE:        0x%lx (%d)\n", CONFIG_SYS_MALLOC_BASE,
 233               CONFIG_SYS_MALLOC_LEN);
 234        printf("CONFIG_SYS_INIT_SP_OFFSET:     0x%lx (%d)\n", CONFIG_SYS_INIT_SP_OFFSET,
 235               CONFIG_SYS_STACK_SIZE);
 236        printf("CONFIG_SYS_PROM_OFFSET:        0x%lx (%d)\n", CONFIG_SYS_PROM_OFFSET,
 237               CONFIG_SYS_PROM_SIZE);
 238        printf("CONFIG_SYS_GBL_DATA_OFFSET:    0x%lx (%d)\n", CONFIG_SYS_GBL_DATA_OFFSET,
 239               GENERATED_GBL_DATA_SIZE);
 240#endif
 241
 242#ifdef CONFIG_POST
 243        post_bootmode_init();
 244        post_run(NULL, POST_ROM | post_bootmode_get(0));
 245#endif
 246
 247#if defined(CONFIG_NEEDS_MANUAL_RELOC)
 248        /*
 249         * We have to relocate the command table manually
 250         */
 251        fixup_cmdtable(&__u_boot_cmd_start,
 252                (ulong)(&__u_boot_cmd_end - &__u_boot_cmd_start));
 253#endif /* defined(CONFIG_NEEDS_MANUAL_RELOC) */
 254
 255#if defined(CONFIG_CMD_AMBAPP) && defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)
 256        puts("AMBA:\n");
 257        do_ambapp_print(NULL, 0, 0, NULL);
 258#endif
 259
 260        /* initialize higher level parts of CPU like time base and timers */
 261        cpu_init_r();
 262
 263        /* start timer */
 264        timer_interrupt_init();
 265
 266        /*
 267         * Enable Interrupts before any calls to udelay,
 268         * the flash driver may use udelay resulting in
 269         * a hang if not timer0 IRQ is enabled.
 270         */
 271        interrupt_init();
 272
 273        /* The Malloc area is immediately below the monitor copy in RAM */
 274        mem_malloc_init(CONFIG_SYS_MALLOC_BASE,
 275                        CONFIG_SYS_MALLOC_END - CONFIG_SYS_MALLOC_BASE);
 276        malloc_bin_reloc();
 277
 278#if !defined(CONFIG_SYS_NO_FLASH)
 279        puts("Flash: ");
 280
 281        if ((flash_size = flash_init()) > 0) {
 282# ifdef CONFIG_SYS_FLASH_CHECKSUM
 283                print_size(flash_size, "");
 284                /*
 285                 * Compute and print flash CRC if flashchecksum is set to 'y'
 286                 *
 287                 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
 288                 */
 289                s = getenv("flashchecksum");
 290                if (s && (*s == 'y')) {
 291                        printf("  CRC: %08lX",
 292                               crc32(0, (const unsigned char *)CONFIG_SYS_FLASH_BASE,
 293                                     flash_size)
 294                            );
 295                }
 296                putc('\n');
 297# else                          /* !CONFIG_SYS_FLASH_CHECKSUM */
 298                print_size(flash_size, "\n");
 299# endif                         /* CONFIG_SYS_FLASH_CHECKSUM */
 300        } else {
 301                puts(failed);
 302                hang();
 303        }
 304
 305        bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;      /* update start of FLASH memory    */
 306        bd->bi_flashsize = flash_size;  /* size of FLASH memory (final value) */
 307#if CONFIG_SYS_MONITOR_BASE == CONFIG_SYS_FLASH_BASE
 308        bd->bi_flashoffset = monitor_flash_len; /* reserved area for startup monitor  */
 309#else
 310        bd->bi_flashoffset = 0;
 311#endif
 312#else                           /* CONFIG_SYS_NO_FLASH */
 313        bd->bi_flashsize = 0;
 314        bd->bi_flashstart = 0;
 315        bd->bi_flashoffset = 0;
 316#endif                          /* !CONFIG_SYS_NO_FLASH */
 317
 318#ifdef CONFIG_SPI
 319# if !defined(CONFIG_ENV_IS_IN_EEPROM)
 320        spi_init_f();
 321# endif
 322        spi_init_r();
 323#endif
 324
 325        /* relocate environment function pointers etc. */
 326        env_relocate();
 327
 328#if defined(CONFIG_BOARD_LATE_INIT)
 329        board_late_init();
 330#endif
 331
 332#ifdef CONFIG_ID_EEPROM
 333        mac_read_from_eeprom();
 334#endif
 335
 336        /* IP Address */
 337        bd->bi_ip_addr = getenv_IPaddr("ipaddr");
 338#if defined(CONFIG_PCI)
 339        /*
 340         * Do pci configuration
 341         */
 342        pci_init();
 343#endif
 344
 345        /* Initialize stdio devices */
 346        stdio_init();
 347
 348        /* Initialize the jump table for applications */
 349        jumptable_init();
 350
 351        /* Initialize the console (after the relocation and devices init) */
 352        console_init_r();
 353
 354#ifdef CONFIG_STATUS_LED
 355        status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
 356#endif
 357
 358        udelay(20);
 359
 360        /* Initialize from environment */
 361        load_addr = getenv_ulong("loadaddr", 16, load_addr);
 362#if defined(CONFIG_CMD_NET)
 363        if ((s = getenv("bootfile")) != NULL) {
 364                copy_filename(BootFile, s, sizeof(BootFile));
 365        }
 366#endif /* CONFIG_CMD_NET */
 367
 368        WATCHDOG_RESET();
 369
 370#if defined(CONFIG_CMD_DOC)
 371        WATCHDOG_RESET();
 372        puts("DOC:   ");
 373        doc_init();
 374#endif
 375
 376#ifdef CONFIG_BITBANGMII
 377        bb_miiphy_init();
 378#endif
 379#if defined(CONFIG_CMD_NET)
 380        WATCHDOG_RESET();
 381        puts("Net:   ");
 382        eth_initialize(bd);
 383#endif
 384
 385#if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R)
 386        WATCHDOG_RESET();
 387        debug("Reset Ethernet PHY\n");
 388        reset_phy();
 389#endif
 390
 391#ifdef CONFIG_POST
 392        post_run(NULL, POST_RAM | post_bootmode_get(0));
 393#endif
 394
 395#if defined(CONFIG_CMD_IDE)
 396        WATCHDOG_RESET();
 397        puts("IDE:   ");
 398        ide_init();
 399#endif /* CONFIG_CMD_IDE */
 400
 401#ifdef CONFIG_LAST_STAGE_INIT
 402        WATCHDOG_RESET();
 403        /*
 404         * Some parts can be only initialized if all others (like
 405         * Interrupts) are up and running (i.e. the PC-style ISA
 406         * keyboard).
 407         */
 408        last_stage_init();
 409#endif
 410
 411#ifdef CONFIG_PS2KBD
 412        puts("PS/2:  ");
 413        kbd_init();
 414#endif
 415        prom_init();
 416
 417        /* main_loop */
 418        for (;;) {
 419                WATCHDOG_RESET();
 420                main_loop();
 421        }
 422
 423}
 424
 425void hang(void)
 426{
 427        puts("### ERROR ### Please RESET the board ###\n");
 428#ifdef CONFIG_SHOW_BOOT_PROGRESS
 429        show_boot_progress(-30);
 430#endif
 431        for (;;) ;
 432}
 433
 434/************************************************************************/
 435