blob: 5e09568b85be46bbf5d3b534397e19012b9f4cf2 [file] [log] [blame]
Bin Meng08e484c2014-12-17 15:50:36 +08001/*
2 * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7#include <config.h>
8#include <asm/post.h>
9
10.globl car_init
11car_init:
12 /*
13 * Note: ebp holds the BIST value (built-in self test) so far, but ebp
14 * will be destroyed through the FSP call, thus we have to test the
15 * BIST value here before we call into FSP.
16 */
17 test %ebp, %ebp
18 jz car_init_start
19 post_code(POST_BIST_FAILURE)
20 jmp die
21
22car_init_start:
23 post_code(POST_CAR_START)
24 lea find_fsp_header_romstack, %esp
25 jmp find_fsp_header
26
27find_fsp_header_ret:
28 /* EAX points to FSP_INFO_HEADER */
29 mov %eax, %ebp
30
31 /* sanity test */
Bin Meng293f4972014-12-17 15:50:42 +080032 cmp $CONFIG_FSP_ADDR, %eax
Bin Meng08e484c2014-12-17 15:50:36 +080033 jb die
34
35 /* calculate TempRamInitEntry address */
36 mov 0x30(%ebp), %eax
37 add 0x1c(%ebp), %eax
38
39 /* call FSP TempRamInitEntry to setup temporary stack */
40 lea temp_ram_init_romstack, %esp
41 jmp *%eax
42
43temp_ram_init_ret:
44 addl $4, %esp
45 cmp $0, %eax
46 jnz car_init_fail
47
48 post_code(POST_CAR_CPU_CACHE)
49
50 /*
51 * The FSP TempRamInit initializes the ecx and edx registers to
52 * point to a temporary but writable memory range (Cache-As-RAM).
53 * ecx: the start of this temporary memory range,
54 * edx: the end of this range.
55 */
56
57 /* stack grows down from top of CAR */
58 movl %edx, %esp
59
60 /*
61 * TODO:
62 *
63 * According to FSP architecture spec, the fsp_init() will not return
64 * to its caller, instead it requires the bootloader to provide a
65 * so-called continuation function to pass into the FSP as a parameter
66 * of fsp_init, and fsp_init() will call that continuation function
67 * directly.
68 *
69 * The call to fsp_init() may need to be moved out of the car_init()
70 * to cpu_init_f() with the help of some inline assembly codes.
71 * Note there is another issue that fsp_init() will setup another stack
72 * using the fsp_init parameter stack_top after DRAM is initialized,
73 * which means any data on the previous stack (on the CAR) gets lost
74 * (ie: U-Boot global_data). FSP is supposed to support such scenario,
75 * however it does not work. This should be revisited in the future.
76 */
77 movl $CONFIG_FSP_TEMP_RAM_ADDR, %eax
78 xorl %edx, %edx
79 xorl %ecx, %ecx
80 call fsp_init
81
82.global fsp_init_done
83fsp_init_done:
84 /*
85 * We come here from FspInit with eax pointing to the HOB list.
86 * Save eax to esi temporarily.
87 */
88 movl %eax, %esi
89 /*
90 * Re-initialize the ebp (BIST) to zero, as we already reach here
91 * which means we passed BIST testing before.
92 */
93 xorl %ebp, %ebp
94 jmp car_init_ret
95
96car_init_fail:
97 post_code(POST_CAR_FAILURE)
98
99die:
100 hlt
101 jmp die
102 hlt
103
104 /*
105 * The function call before CAR initialization is tricky. It cannot
106 * be called using the 'call' instruction but only the 'jmp' with
107 * the help of a handcrafted stack in the ROM. The stack needs to
108 * contain the function return address as well as the parameters.
109 */
110 .balign 4
111find_fsp_header_romstack:
112 .long find_fsp_header_ret
113
114 .balign 4
115temp_ram_init_romstack:
116 .long temp_ram_init_ret
117 .long temp_ram_init_params
118temp_ram_init_params:
Simon Glass8bfe0662014-12-17 15:50:37 +0800119_dt_ucode_base_size:
120 /* These next two fields are filled in by ifdtool */
121 .long 0 /* microcode base */
122 .long 0 /* microcode size */
Bin Meng08e484c2014-12-17 15:50:36 +0800123 .long CONFIG_SYS_MONITOR_BASE /* code region base */
124 .long CONFIG_SYS_MONITOR_LEN /* code region size */