uboot/common/board_f.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2011 The Chromium OS Authors.
   3 * (C) Copyright 2002-2006
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 *
   6 * (C) Copyright 2002
   7 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
   8 * Marius Groeger <mgroeger@sysgo.de>
   9 *
  10 * SPDX-License-Identifier:     GPL-2.0+
  11 */
  12
  13#include <common.h>
  14#include <linux/compiler.h>
  15#include <version.h>
  16#include <environment.h>
  17#include <fdtdec.h>
  18#include <fs.h>
  19#if defined(CONFIG_CMD_IDE)
  20#include <ide.h>
  21#endif
  22#include <i2c.h>
  23#include <initcall.h>
  24#include <logbuff.h>
  25
  26/* TODO: Can we move these into arch/ headers? */
  27#ifdef CONFIG_8xx
  28#include <mpc8xx.h>
  29#endif
  30#ifdef CONFIG_5xx
  31#include <mpc5xx.h>
  32#endif
  33#ifdef CONFIG_MPC5xxx
  34#include <mpc5xxx.h>
  35#endif
  36
  37#include <os.h>
  38#include <post.h>
  39#include <spi.h>
  40#include <trace.h>
  41#include <watchdog.h>
  42#include <asm/errno.h>
  43#include <asm/io.h>
  44#ifdef CONFIG_MP
  45#include <asm/mp.h>
  46#endif
  47#include <asm/sections.h>
  48#ifdef CONFIG_X86
  49#include <asm/init_helpers.h>
  50#include <asm/relocate.h>
  51#endif
  52#ifdef CONFIG_SANDBOX
  53#include <asm/state.h>
  54#endif
  55#include <linux/compiler.h>
  56
  57/*
  58 * Pointer to initial global data area
  59 *
  60 * Here we initialize it if needed.
  61 */
  62#ifdef XTRN_DECLARE_GLOBAL_DATA_PTR
  63#undef  XTRN_DECLARE_GLOBAL_DATA_PTR
  64#define XTRN_DECLARE_GLOBAL_DATA_PTR    /* empty = allocate here */
  65DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR);
  66#else
  67DECLARE_GLOBAL_DATA_PTR;
  68#endif
  69
  70/*
  71 * sjg: IMO this code should be
  72 * refactored to a single function, something like:
  73 *
  74 * void led_set_state(enum led_colour_t colour, int on);
  75 */
  76/************************************************************************
  77 * Coloured LED functionality
  78 ************************************************************************
  79 * May be supplied by boards if desired
  80 */
  81inline void __coloured_LED_init(void) {}
  82void coloured_LED_init(void)
  83        __attribute__((weak, alias("__coloured_LED_init")));
  84inline void __red_led_on(void) {}
  85void red_led_on(void) __attribute__((weak, alias("__red_led_on")));
  86inline void __red_led_off(void) {}
  87void red_led_off(void) __attribute__((weak, alias("__red_led_off")));
  88inline void __green_led_on(void) {}
  89void green_led_on(void) __attribute__((weak, alias("__green_led_on")));
  90inline void __green_led_off(void) {}
  91void green_led_off(void) __attribute__((weak, alias("__green_led_off")));
  92inline void __yellow_led_on(void) {}
  93void yellow_led_on(void) __attribute__((weak, alias("__yellow_led_on")));
  94inline void __yellow_led_off(void) {}
  95void yellow_led_off(void) __attribute__((weak, alias("__yellow_led_off")));
  96inline void __blue_led_on(void) {}
  97void blue_led_on(void) __attribute__((weak, alias("__blue_led_on")));
  98inline void __blue_led_off(void) {}
  99void blue_led_off(void) __attribute__((weak, alias("__blue_led_off")));
 100
 101/*
 102 * Why is gd allocated a register? Prior to reloc it might be better to
 103 * just pass it around to each function in this file?
 104 *
 105 * After reloc one could argue that it is hardly used and doesn't need
 106 * to be in a register. Or if it is it should perhaps hold pointers to all
 107 * global data for all modules, so that post-reloc we can avoid the massive
 108 * literal pool we get on ARM. Or perhaps just encourage each module to use
 109 * a structure...
 110 */
 111
 112/*
 113 * Could the CONFIG_SPL_BUILD infection become a flag in gd?
 114 */
 115
 116#if defined(CONFIG_WATCHDOG)
 117static int init_func_watchdog_init(void)
 118{
 119        puts("       Watchdog enabled\n");
 120        WATCHDOG_RESET();
 121
 122        return 0;
 123}
 124
 125int init_func_watchdog_reset(void)
 126{
 127        WATCHDOG_RESET();
 128
 129        return 0;
 130}
 131#endif /* CONFIG_WATCHDOG */
 132
 133void __board_add_ram_info(int use_default)
 134{
 135        /* please define platform specific board_add_ram_info() */
 136}
 137
 138void board_add_ram_info(int)
 139        __attribute__ ((weak, alias("__board_add_ram_info")));
 140
 141static int init_baud_rate(void)
 142{
 143        gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
 144        return 0;
 145}
 146
 147static int display_text_info(void)
 148{
 149#ifndef CONFIG_SANDBOX
 150        ulong bss_start, bss_end;
 151
 152#ifdef CONFIG_SYS_SYM_OFFSETS
 153        bss_start = _bss_start_ofs + _TEXT_BASE;
 154        bss_end = _bss_end_ofs + _TEXT_BASE;
 155#else
 156        bss_start = (ulong)&__bss_start;
 157        bss_end = (ulong)&__bss_end;
 158#endif
 159        debug("U-Boot code: %08X -> %08lX  BSS: -> %08lX\n",
 160              CONFIG_SYS_TEXT_BASE, bss_start, bss_end);
 161#endif
 162
 163#ifdef CONFIG_MODEM_SUPPORT
 164        debug("Modem Support enabled\n");
 165#endif
 166#ifdef CONFIG_USE_IRQ
 167        debug("IRQ Stack: %08lx\n", IRQ_STACK_START);
 168        debug("FIQ Stack: %08lx\n", FIQ_STACK_START);
 169#endif
 170
 171        return 0;
 172}
 173
 174static int announce_dram_init(void)
 175{
 176        puts("DRAM:  ");
 177        return 0;
 178}
 179
 180#ifdef CONFIG_PPC
 181static int init_func_ram(void)
 182{
 183#ifdef  CONFIG_BOARD_TYPES
 184        int board_type = gd->board_type;
 185#else
 186        int board_type = 0;     /* use dummy arg */
 187#endif
 188
 189        gd->ram_size = initdram(board_type);
 190
 191        if (gd->ram_size > 0)
 192                return 0;
 193
 194        puts("*** failed ***\n");
 195        return 1;
 196}
 197#endif
 198
 199static int show_dram_config(void)
 200{
 201        ulong size;
 202
 203#ifdef CONFIG_NR_DRAM_BANKS
 204        int i;
 205
 206        debug("\nRAM Configuration:\n");
 207        for (i = size = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 208                size += gd->bd->bi_dram[i].size;
 209                debug("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
 210#ifdef DEBUG
 211                print_size(gd->bd->bi_dram[i].size, "\n");
 212#endif
 213        }
 214        debug("\nDRAM:  ");
 215#else
 216        size = gd->ram_size;
 217#endif
 218
 219        print_size(size, "");
 220        board_add_ram_info(0);
 221        putc('\n');
 222
 223        return 0;
 224}
 225
 226ulong get_effective_memsize(void)
 227{
 228#ifndef CONFIG_VERY_BIG_RAM
 229        return gd->ram_size;
 230#else
 231        /* limit stack to what we can reasonable map */
 232        return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
 233                CONFIG_MAX_MEM_MAPPED : gd->ram_size);
 234#endif
 235}
 236
 237void __dram_init_banksize(void)
 238{
 239#if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE)
 240        gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
 241        gd->bd->bi_dram[0].size = get_effective_memsize();
 242#endif
 243}
 244
 245void dram_init_banksize(void)
 246        __attribute__((weak, alias("__dram_init_banksize")));
 247
 248#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
 249static int init_func_i2c(void)
 250{
 251        puts("I2C:   ");
 252#ifdef CONFIG_SYS_I2C
 253        i2c_init_all();
 254#else
 255        i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 256#endif
 257        puts("ready\n");
 258        return 0;
 259}
 260#endif
 261
 262#if defined(CONFIG_HARD_SPI)
 263static int init_func_spi(void)
 264{
 265        puts("SPI:   ");
 266        spi_init();
 267        puts("ready\n");
 268        return 0;
 269}
 270#endif
 271
 272__maybe_unused
 273static int zero_global_data(void)
 274{
 275        memset((void *)gd, '\0', sizeof(gd_t));
 276
 277        return 0;
 278}
 279
 280static int setup_mon_len(void)
 281{
 282#ifdef CONFIG_SYS_SYM_OFFSETS
 283        gd->mon_len = _bss_end_ofs;
 284#elif defined(CONFIG_SANDBOX)
 285        gd->mon_len = (ulong)&_end - (ulong)_init;
 286#else
 287        /* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */
 288        gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
 289#endif
 290        return 0;
 291}
 292
 293__weak int arch_cpu_init(void)
 294{
 295        return 0;
 296}
 297
 298#ifdef CONFIG_OF_HOSTFILE
 299
 300#define CHECK(x)                err = (x); if (err) goto failed;
 301
 302/* Create an empty device tree blob */
 303static int make_empty_fdt(void *fdt)
 304{
 305        int err;
 306
 307        CHECK(fdt_create(fdt, 256));
 308        CHECK(fdt_finish_reservemap(fdt));
 309        CHECK(fdt_begin_node(fdt, ""));
 310        CHECK(fdt_end_node(fdt));
 311        CHECK(fdt_finish(fdt));
 312
 313        return 0;
 314failed:
 315        printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
 316        return -EACCES;
 317}
 318
 319static int read_fdt_from_file(void)
 320{
 321        struct sandbox_state *state = state_get_current();
 322        void *blob;
 323        int size;
 324        int err;
 325
 326        blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
 327        if (!state->fdt_fname) {
 328                err = make_empty_fdt(blob);
 329                if (!err)
 330                        goto done;
 331                return err;
 332        }
 333        err = fs_set_blk_dev("host", NULL, FS_TYPE_SANDBOX);
 334        if (err)
 335                return err;
 336        size = fs_read(state->fdt_fname, CONFIG_SYS_FDT_LOAD_ADDR, 0, 0);
 337        if (size < 0)
 338                return -EIO;
 339
 340done:
 341        gd->fdt_blob = blob;
 342
 343        return 0;
 344}
 345#endif
 346
 347#ifdef CONFIG_SANDBOX
 348static int setup_ram_buf(void)
 349{
 350        struct sandbox_state *state = state_get_current();
 351
 352        gd->arch.ram_buf = state->ram_buf;
 353        gd->ram_size = state->ram_size;
 354
 355        return 0;
 356}
 357#endif
 358
 359static int setup_fdt(void)
 360{
 361#ifdef CONFIG_OF_EMBED
 362        /* Get a pointer to the FDT */
 363        gd->fdt_blob = _binary_dt_dtb_start;
 364#elif defined CONFIG_OF_SEPARATE
 365        /* FDT is at end of image */
 366# ifdef CONFIG_SYS_SYM_OFFSETS
 367        gd->fdt_blob = (void *)(_end_ofs + CONFIG_SYS_TEXT_BASE);
 368# else
 369        gd->fdt_blob = (ulong *)&_end;
 370# endif
 371#elif defined(CONFIG_OF_HOSTFILE)
 372        if (read_fdt_from_file()) {
 373                puts("Failed to read control FDT\n");
 374                return -1;
 375        }
 376#endif
 377        /* Allow the early environment to override the fdt address */
 378        gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
 379                                                (uintptr_t)gd->fdt_blob);
 380        return 0;
 381}
 382
 383/* Get the top of usable RAM */
 384__weak ulong board_get_usable_ram_top(ulong total_size)
 385{
 386        return gd->ram_top;
 387}
 388
 389static int setup_dest_addr(void)
 390{
 391        debug("Monitor len: %08lX\n", gd->mon_len);
 392        /*
 393         * Ram is setup, size stored in gd !!
 394         */
 395        debug("Ram size: %08lX\n", (ulong)gd->ram_size);
 396#if defined(CONFIG_SYS_MEM_TOP_HIDE)
 397        /*
 398         * Subtract specified amount of memory to hide so that it won't
 399         * get "touched" at all by U-Boot. By fixing up gd->ram_size
 400         * the Linux kernel should now get passed the now "corrected"
 401         * memory size and won't touch it either. This should work
 402         * for arch/ppc and arch/powerpc. Only Linux board ports in
 403         * arch/powerpc with bootwrapper support, that recalculate the
 404         * memory size from the SDRAM controller setup will have to
 405         * get fixed.
 406         */
 407        gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE;
 408#endif
 409#ifdef CONFIG_SYS_SDRAM_BASE
 410        gd->ram_top = CONFIG_SYS_SDRAM_BASE;
 411#endif
 412        gd->ram_top += get_effective_memsize();
 413        gd->ram_top = board_get_usable_ram_top(gd->mon_len);
 414        gd->relocaddr = gd->ram_top;
 415        debug("Ram top: %08lX\n", (ulong)gd->ram_top);
 416#if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))
 417        /*
 418         * We need to make sure the location we intend to put secondary core
 419         * boot code is reserved and not used by any part of u-boot
 420         */
 421        if (gd->relocaddr > determine_mp_bootpg(NULL)) {
 422                gd->relocaddr = determine_mp_bootpg(NULL);
 423                debug("Reserving MP boot page to %08lx\n", gd->relocaddr);
 424        }
 425#endif
 426        return 0;
 427}
 428
 429#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
 430static int reserve_logbuffer(void)
 431{
 432        /* reserve kernel log buffer */
 433        gd->relocaddr -= LOGBUFF_RESERVE;
 434        debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
 435                gd->relocaddr);
 436        return 0;
 437}
 438#endif
 439
 440#ifdef CONFIG_PRAM
 441/* reserve protected RAM */
 442static int reserve_pram(void)
 443{
 444        ulong reg;
 445
 446        reg = getenv_ulong("pram", 10, CONFIG_PRAM);
 447        gd->relocaddr -= (reg << 10);           /* size is in kB */
 448        debug("Reserving %ldk for protected RAM at %08lx\n", reg,
 449              gd->relocaddr);
 450        return 0;
 451}
 452#endif /* CONFIG_PRAM */
 453
 454/* Round memory pointer down to next 4 kB limit */
 455static int reserve_round_4k(void)
 456{
 457        gd->relocaddr &= ~(4096 - 1);
 458        return 0;
 459}
 460
 461#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
 462                defined(CONFIG_ARM)
 463static int reserve_mmu(void)
 464{
 465        /* reserve TLB table */
 466        gd->arch.tlb_size = PGTABLE_SIZE;
 467        gd->relocaddr -= gd->arch.tlb_size;
 468
 469        /* round down to next 64 kB limit */
 470        gd->relocaddr &= ~(0x10000 - 1);
 471
 472        gd->arch.tlb_addr = gd->relocaddr;
 473        debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,
 474              gd->arch.tlb_addr + gd->arch.tlb_size);
 475        return 0;
 476}
 477#endif
 478
 479#ifdef CONFIG_LCD
 480static int reserve_lcd(void)
 481{
 482#ifdef CONFIG_FB_ADDR
 483        gd->fb_base = CONFIG_FB_ADDR;
 484#else
 485        /* reserve memory for LCD display (always full pages) */
 486        gd->relocaddr = lcd_setmem(gd->relocaddr);
 487        gd->fb_base = gd->relocaddr;
 488#endif /* CONFIG_FB_ADDR */
 489        return 0;
 490}
 491#endif /* CONFIG_LCD */
 492
 493static int reserve_trace(void)
 494{
 495#ifdef CONFIG_TRACE
 496        gd->relocaddr -= CONFIG_TRACE_BUFFER_SIZE;
 497        gd->trace_buff = map_sysmem(gd->relocaddr, CONFIG_TRACE_BUFFER_SIZE);
 498        debug("Reserving %dk for trace data at: %08lx\n",
 499              CONFIG_TRACE_BUFFER_SIZE >> 10, gd->relocaddr);
 500#endif
 501
 502        return 0;
 503}
 504
 505#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) \
 506                && !defined(CONFIG_ARM) && !defined(CONFIG_X86)
 507static int reserve_video(void)
 508{
 509        /* reserve memory for video display (always full pages) */
 510        gd->relocaddr = video_setmem(gd->relocaddr);
 511        gd->fb_base = gd->relocaddr;
 512
 513        return 0;
 514}
 515#endif
 516
 517static int reserve_uboot(void)
 518{
 519        /*
 520         * reserve memory for U-Boot code, data & bss
 521         * round down to next 4 kB limit
 522         */
 523        gd->relocaddr -= gd->mon_len;
 524        gd->relocaddr &= ~(4096 - 1);
 525#ifdef CONFIG_E500
 526        /* round down to next 64 kB limit so that IVPR stays aligned */
 527        gd->relocaddr &= ~(65536 - 1);
 528#endif
 529
 530        debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10,
 531              gd->relocaddr);
 532
 533        gd->start_addr_sp = gd->relocaddr;
 534
 535        return 0;
 536}
 537
 538#ifndef CONFIG_SPL_BUILD
 539/* reserve memory for malloc() area */
 540static int reserve_malloc(void)
 541{
 542        gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;
 543        debug("Reserving %dk for malloc() at: %08lx\n",
 544                        TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp);
 545        return 0;
 546}
 547
 548/* (permanently) allocate a Board Info struct */
 549static int reserve_board(void)
 550{
 551        gd->start_addr_sp -= sizeof(bd_t);
 552        gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t));
 553        memset(gd->bd, '\0', sizeof(bd_t));
 554        debug("Reserving %zu Bytes for Board Info at: %08lx\n",
 555                        sizeof(bd_t), gd->start_addr_sp);
 556        return 0;
 557}
 558#endif
 559
 560static int setup_machine(void)
 561{
 562#ifdef CONFIG_MACH_TYPE
 563        gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */
 564#endif
 565        return 0;
 566}
 567
 568static int reserve_global_data(void)
 569{
 570        gd->start_addr_sp -= sizeof(gd_t);
 571        gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t));
 572        debug("Reserving %zu Bytes for Global Data at: %08lx\n",
 573                        sizeof(gd_t), gd->start_addr_sp);
 574        return 0;
 575}
 576
 577static int reserve_fdt(void)
 578{
 579        /*
 580         * If the device tree is sitting immediate above our image then we
 581         * must relocate it. If it is embedded in the data section, then it
 582         * will be relocated with other data.
 583         */
 584        if (gd->fdt_blob) {
 585                gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
 586
 587                gd->start_addr_sp -= gd->fdt_size;
 588                gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);
 589                debug("Reserving %lu Bytes for FDT at: %08lx\n",
 590                      gd->fdt_size, gd->start_addr_sp);
 591        }
 592
 593        return 0;
 594}
 595
 596static int reserve_stacks(void)
 597{
 598#ifdef CONFIG_SPL_BUILD
 599# ifdef CONFIG_ARM
 600        gd->start_addr_sp -= 128;       /* leave 32 words for abort-stack */
 601        gd->irq_sp = gd->start_addr_sp;
 602# endif
 603#else
 604# ifdef CONFIG_PPC
 605        ulong *s;
 606# endif
 607
 608        /* setup stack pointer for exceptions */
 609        gd->start_addr_sp -= 16;
 610        gd->start_addr_sp &= ~0xf;
 611        gd->irq_sp = gd->start_addr_sp;
 612
 613        /*
 614         * Handle architecture-specific things here
 615         * TODO(sjg@chromium.org): Perhaps create arch_reserve_stack()
 616         * to handle this and put in arch/xxx/lib/stack.c
 617         */
 618# if defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
 619#  ifdef CONFIG_USE_IRQ
 620        gd->start_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);
 621        debug("Reserving %zu Bytes for IRQ stack at: %08lx\n",
 622                CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->start_addr_sp);
 623
 624        /* 8-byte alignment for ARM ABI compliance */
 625        gd->start_addr_sp &= ~0x07;
 626#  endif
 627        /* leave 3 words for abort-stack, plus 1 for alignment */
 628        gd->start_addr_sp -= 16;
 629# elif defined(CONFIG_PPC)
 630        /* Clear initial stack frame */
 631        s = (ulong *) gd->start_addr_sp;
 632        *s = 0; /* Terminate back chain */
 633        *++s = 0; /* NULL return address */
 634# endif /* Architecture specific code */
 635
 636        return 0;
 637#endif
 638}
 639
 640static int display_new_sp(void)
 641{
 642        debug("New Stack Pointer is: %08lx\n", gd->start_addr_sp);
 643
 644        return 0;
 645}
 646
 647#ifdef CONFIG_PPC
 648static int setup_board_part1(void)
 649{
 650        bd_t *bd = gd->bd;
 651
 652        /*
 653         * Save local variables to board info struct
 654         */
 655
 656        bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;        /* start of memory */
 657        bd->bi_memsize = gd->ram_size;                  /* size in bytes */
 658
 659#ifdef CONFIG_SYS_SRAM_BASE
 660        bd->bi_sramstart = CONFIG_SYS_SRAM_BASE;        /* start of SRAM */
 661        bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE;         /* size  of SRAM */
 662#endif
 663
 664#if defined(CONFIG_8xx) || defined(CONFIG_8260) || defined(CONFIG_5xx) || \
 665                defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
 666        bd->bi_immr_base = CONFIG_SYS_IMMR;     /* base  of IMMR register     */
 667#endif
 668#if defined(CONFIG_MPC5xxx)
 669        bd->bi_mbar_base = CONFIG_SYS_MBAR;     /* base of internal registers */
 670#endif
 671#if defined(CONFIG_MPC83xx)
 672        bd->bi_immrbar = CONFIG_SYS_IMMR;
 673#endif
 674
 675        return 0;
 676}
 677
 678static int setup_board_part2(void)
 679{
 680        bd_t *bd = gd->bd;
 681
 682        bd->bi_intfreq = gd->cpu_clk;   /* Internal Freq, in Hz */
 683        bd->bi_busfreq = gd->bus_clk;   /* Bus Freq,      in Hz */
 684#if defined(CONFIG_CPM2)
 685        bd->bi_cpmfreq = gd->arch.cpm_clk;
 686        bd->bi_brgfreq = gd->arch.brg_clk;
 687        bd->bi_sccfreq = gd->arch.scc_clk;
 688        bd->bi_vco = gd->arch.vco_out;
 689#endif /* CONFIG_CPM2 */
 690#if defined(CONFIG_MPC512X)
 691        bd->bi_ipsfreq = gd->arch.ips_clk;
 692#endif /* CONFIG_MPC512X */
 693#if defined(CONFIG_MPC5xxx)
 694        bd->bi_ipbfreq = gd->arch.ipb_clk;
 695        bd->bi_pcifreq = gd->pci_clk;
 696#endif /* CONFIG_MPC5xxx */
 697
 698        return 0;
 699}
 700#endif
 701
 702#ifdef CONFIG_SYS_EXTBDINFO
 703static int setup_board_extra(void)
 704{
 705        bd_t *bd = gd->bd;
 706
 707        strncpy((char *) bd->bi_s_version, "1.2", sizeof(bd->bi_s_version));
 708        strncpy((char *) bd->bi_r_version, U_BOOT_VERSION,
 709                sizeof(bd->bi_r_version));
 710
 711        bd->bi_procfreq = gd->cpu_clk;  /* Processor Speed, In Hz */
 712        bd->bi_plb_busfreq = gd->bus_clk;
 713#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \
 714                defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
 715                defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 716        bd->bi_pci_busfreq = get_PCI_freq();
 717        bd->bi_opbfreq = get_OPB_freq();
 718#elif defined(CONFIG_XILINX_405)
 719        bd->bi_pci_busfreq = get_PCI_freq();
 720#endif
 721
 722        return 0;
 723}
 724#endif
 725
 726#ifdef CONFIG_POST
 727static int init_post(void)
 728{
 729        post_bootmode_init();
 730        post_run(NULL, POST_ROM | post_bootmode_get(0));
 731
 732        return 0;
 733}
 734#endif
 735
 736static int setup_baud_rate(void)
 737{
 738        /* Ick, can we get rid of this line? */
 739        gd->bd->bi_baudrate = gd->baudrate;
 740
 741        return 0;
 742}
 743
 744static int setup_dram_config(void)
 745{
 746        /* Ram is board specific, so move it to board code ... */
 747        dram_init_banksize();
 748
 749        return 0;
 750}
 751
 752static int reloc_fdt(void)
 753{
 754        if (gd->new_fdt) {
 755                memcpy(gd->new_fdt, gd->fdt_blob, gd->fdt_size);
 756                gd->fdt_blob = gd->new_fdt;
 757        }
 758
 759        return 0;
 760}
 761
 762static int setup_reloc(void)
 763{
 764        gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
 765        memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
 766
 767        debug("Relocation Offset is: %08lx\n", gd->reloc_off);
 768        debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n",
 769              gd->relocaddr, (ulong)map_to_sysmem(gd->new_gd),
 770              gd->start_addr_sp);
 771
 772        return 0;
 773}
 774
 775/* ARM calls relocate_code from its crt0.S */
 776#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
 777
 778static int jump_to_copy(void)
 779{
 780        /*
 781         * x86 is special, but in a nice way. It uses a trampoline which
 782         * enables the dcache if possible.
 783         *
 784         * For now, other archs use relocate_code(), which is implemented
 785         * similarly for all archs. When we do generic relocation, hopefully
 786         * we can make all archs enable the dcache prior to relocation.
 787         */
 788#ifdef CONFIG_X86
 789        /*
 790         * SDRAM and console are now initialised. The final stack can now
 791         * be setup in SDRAM. Code execution will continue in Flash, but
 792         * with the stack in SDRAM and Global Data in temporary memory
 793         * (CPU cache)
 794         */
 795        board_init_f_r_trampoline(gd->start_addr_sp);
 796#else
 797        relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr);
 798#endif
 799
 800        return 0;
 801}
 802#endif
 803
 804/* Record the board_init_f() bootstage (after arch_cpu_init()) */
 805static int mark_bootstage(void)
 806{
 807        bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");
 808
 809        return 0;
 810}
 811
 812static init_fnc_t init_sequence_f[] = {
 813#ifdef CONFIG_SANDBOX
 814        setup_ram_buf,
 815#endif
 816        setup_mon_len,
 817        setup_fdt,
 818        trace_early_init,
 819#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
 820        /* TODO: can this go into arch_cpu_init()? */
 821        probecpu,
 822#endif
 823        arch_cpu_init,          /* basic arch cpu dependent setup */
 824#ifdef CONFIG_X86
 825        cpu_init_f,             /* TODO(sjg@chromium.org): remove */
 826# ifdef CONFIG_OF_CONTROL
 827        find_fdt,               /* TODO(sjg@chromium.org): remove */
 828# endif
 829#endif
 830        mark_bootstage,
 831#ifdef CONFIG_OF_CONTROL
 832        fdtdec_check_fdt,
 833#endif
 834#if defined(CONFIG_BOARD_EARLY_INIT_F)
 835        board_early_init_f,
 836#endif
 837        /* TODO: can any of this go into arch_cpu_init()? */
 838#if defined(CONFIG_PPC) && !defined(CONFIG_8xx_CPUCLK_DEFAULT)
 839        get_clocks,             /* get CPU and bus clocks (etc.) */
 840#if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \
 841                && !defined(CONFIG_TQM885D)
 842        adjust_sdram_tbs_8xx,
 843#endif
 844        /* TODO: can we rename this to timer_init()? */
 845        init_timebase,
 846#endif
 847#ifdef CONFIG_ARM
 848        timer_init,             /* initialize timer */
 849#endif
 850#ifdef CONFIG_SYS_ALLOC_DPRAM
 851#if !defined(CONFIG_CPM2)
 852        dpram_init,
 853#endif
 854#endif
 855#if defined(CONFIG_BOARD_POSTCLK_INIT)
 856        board_postclk_init,
 857#endif
 858#ifdef CONFIG_FSL_ESDHC
 859        get_clocks,
 860#endif
 861        env_init,               /* initialize environment */
 862#if defined(CONFIG_8xx_CPUCLK_DEFAULT)
 863        /* get CPU and bus clocks according to the environment variable */
 864        get_clocks_866,
 865        /* adjust sdram refresh rate according to the new clock */
 866        sdram_adjust_866,
 867        init_timebase,
 868#endif
 869        init_baud_rate,         /* initialze baudrate settings */
 870        serial_init,            /* serial communications setup */
 871        console_init_f,         /* stage 1 init of console */
 872#ifdef CONFIG_SANDBOX
 873        sandbox_early_getopt_check,
 874#endif
 875#ifdef CONFIG_OF_CONTROL
 876        fdtdec_prepare_fdt,
 877#endif
 878        display_options,        /* say that we are here */
 879        display_text_info,      /* show debugging info if required */
 880#if defined(CONFIG_8260)
 881        prt_8260_rsr,
 882        prt_8260_clks,
 883#endif /* CONFIG_8260 */
 884#if defined(CONFIG_MPC83xx)
 885        prt_83xx_rsr,
 886#endif
 887#ifdef CONFIG_PPC
 888        checkcpu,
 889#endif
 890#if defined(CONFIG_DISPLAY_CPUINFO)
 891        print_cpuinfo,          /* display cpu info (and speed) */
 892#endif
 893#if defined(CONFIG_MPC5xxx)
 894        prt_mpc5xxx_clks,
 895#endif /* CONFIG_MPC5xxx */
 896#if defined(CONFIG_DISPLAY_BOARDINFO)
 897        checkboard,             /* display board info */
 898#endif
 899        INIT_FUNC_WATCHDOG_INIT
 900#if defined(CONFIG_MISC_INIT_F)
 901        misc_init_f,
 902#endif
 903        INIT_FUNC_WATCHDOG_RESET
 904#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
 905        init_func_i2c,
 906#endif
 907#if defined(CONFIG_HARD_SPI)
 908        init_func_spi,
 909#endif
 910#ifdef CONFIG_X86
 911        dram_init_f,            /* configure available RAM banks */
 912        calculate_relocation_address,
 913#endif
 914        announce_dram_init,
 915        /* TODO: unify all these dram functions? */
 916#ifdef CONFIG_ARM
 917        dram_init,              /* configure available RAM banks */
 918#endif
 919#ifdef CONFIG_PPC
 920        init_func_ram,
 921#endif
 922#ifdef CONFIG_POST
 923        post_init_f,
 924#endif
 925        INIT_FUNC_WATCHDOG_RESET
 926#if defined(CONFIG_SYS_DRAM_TEST)
 927        testdram,
 928#endif /* CONFIG_SYS_DRAM_TEST */
 929        INIT_FUNC_WATCHDOG_RESET
 930
 931#ifdef CONFIG_POST
 932        init_post,
 933#endif
 934        INIT_FUNC_WATCHDOG_RESET
 935        /*
 936         * Now that we have DRAM mapped and working, we can
 937         * relocate the code and continue running from DRAM.
 938         *
 939         * Reserve memory at end of RAM for (top down in that order):
 940         *  - area that won't get touched by U-Boot and Linux (optional)
 941         *  - kernel log buffer
 942         *  - protected RAM
 943         *  - LCD framebuffer
 944         *  - monitor code
 945         *  - board info struct
 946         */
 947        setup_dest_addr,
 948#if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
 949        reserve_logbuffer,
 950#endif
 951#ifdef CONFIG_PRAM
 952        reserve_pram,
 953#endif
 954        reserve_round_4k,
 955#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) && \
 956                defined(CONFIG_ARM)
 957        reserve_mmu,
 958#endif
 959#ifdef CONFIG_LCD
 960        reserve_lcd,
 961#endif
 962        reserve_trace,
 963        /* TODO: Why the dependency on CONFIG_8xx? */
 964#if defined(CONFIG_VIDEO) && (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) \
 965                && !defined(CONFIG_ARM) && !defined(CONFIG_X86)
 966        reserve_video,
 967#endif
 968        reserve_uboot,
 969#ifndef CONFIG_SPL_BUILD
 970        reserve_malloc,
 971        reserve_board,
 972#endif
 973        setup_machine,
 974        reserve_global_data,
 975        reserve_fdt,
 976        reserve_stacks,
 977        setup_dram_config,
 978        show_dram_config,
 979#ifdef CONFIG_PPC
 980        setup_board_part1,
 981        INIT_FUNC_WATCHDOG_RESET
 982        setup_board_part2,
 983#endif
 984        setup_baud_rate,
 985        display_new_sp,
 986#ifdef CONFIG_SYS_EXTBDINFO
 987        setup_board_extra,
 988#endif
 989        INIT_FUNC_WATCHDOG_RESET
 990        reloc_fdt,
 991        setup_reloc,
 992#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
 993        jump_to_copy,
 994#endif
 995        NULL,
 996};
 997
 998void board_init_f(ulong boot_flags)
 999{
1000#ifndef CONFIG_X86
1001        gd_t data;
1002
1003        gd = &data;
1004#endif
1005
1006        /*
1007         * Clear global data before it is accessed at debug print
1008         * in initcall_run_list. Otherwise the debug print probably
1009         * get the wrong vaule of gd->have_console.
1010         */
1011#if !defined(CONFIG_CPM2) && !defined(CONFIG_MPC512X) && \
1012                !defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \
1013                !defined(CONFIG_MPC86xx) && !defined(CONFIG_X86)
1014        zero_global_data();
1015#endif
1016
1017        gd->flags = boot_flags;
1018        gd->have_console = 0;
1019
1020        if (initcall_run_list(init_sequence_f))
1021                hang();
1022
1023#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
1024        /* NOTREACHED - jump_to_copy() does not return */
1025        hang();
1026#endif
1027}
1028
1029#ifdef CONFIG_X86
1030/*
1031 * For now this code is only used on x86.
1032 *
1033 * init_sequence_f_r is the list of init functions which are run when
1034 * U-Boot is executing from Flash with a semi-limited 'C' environment.
1035 * The following limitations must be considered when implementing an
1036 * '_f_r' function:
1037 *  - 'static' variables are read-only
1038 *  - Global Data (gd->xxx) is read/write
1039 *
1040 * The '_f_r' sequence must, as a minimum, copy U-Boot to RAM (if
1041 * supported).  It _should_, if possible, copy global data to RAM and
1042 * initialise the CPU caches (to speed up the relocation process)
1043 *
1044 * NOTE: At present only x86 uses this route, but it is intended that
1045 * all archs will move to this when generic relocation is implemented.
1046 */
1047static init_fnc_t init_sequence_f_r[] = {
1048        init_cache_f_r,
1049        copy_uboot_to_ram,
1050        clear_bss,
1051        do_elf_reloc_fixups,
1052
1053        NULL,
1054};
1055
1056void board_init_f_r(void)
1057{
1058        if (initcall_run_list(init_sequence_f_r))
1059                hang();
1060
1061        /*
1062         * U-Boot has been copied into SDRAM, the BSS has been cleared etc.
1063         * Transfer execution from Flash to RAM by calculating the address
1064         * of the in-RAM copy of board_init_r() and calling it
1065         */
1066        (board_init_r + gd->reloc_off)(gd, gd->relocaddr);
1067
1068        /* NOTREACHED - board_init_r() does not return */
1069        hang();
1070}
1071#endif /* CONFIG_X86 */
1072