~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/common/board_f.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

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