blob: 5d5d1a9ca749d9ad4acc1b83f27af4892034631e [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Simon Glass030777d2017-01-16 07:03:56 -07002/*
3 * Copyright (c) 2016 Google, Inc
Simon Glass030777d2017-01-16 07:03:56 -07004 */
5
6#include <common.h>
7#include <debug_uart.h>
Simon Glass7cf5fe02019-05-02 10:52:12 -06008#include <malloc.h>
Simon Glass030777d2017-01-16 07:03:56 -07009#include <spl.h>
10#include <asm/cpu.h>
Simon Glass7cf5fe02019-05-02 10:52:12 -060011#include <asm/mrccache.h>
Simon Glass030777d2017-01-16 07:03:56 -070012#include <asm/mtrr.h>
13#include <asm/processor.h>
14#include <asm-generic/sections.h>
15
16DECLARE_GLOBAL_DATA_PTR;
17
Bin Meng2240fde2017-01-18 03:32:53 -080018__weak int arch_cpu_init_dm(void)
19{
20 return 0;
21}
22
Simon Glass030777d2017-01-16 07:03:56 -070023static int x86_spl_init(void)
24{
Simon Glass7cf5fe02019-05-02 10:52:12 -060025#ifndef CONFIG_TPL
Simon Glass030777d2017-01-16 07:03:56 -070026 /*
27 * TODO(sjg@chromium.org): We use this area of RAM for the stack
28 * and global_data in SPL. Once U-Boot starts up and releocates it
29 * is not needed. We could make this a CONFIG option or perhaps
30 * place it immediately below CONFIG_SYS_TEXT_BASE.
31 */
32 char *ptr = (char *)0x110000;
Simon Glass7cf5fe02019-05-02 10:52:12 -060033#endif
Simon Glass030777d2017-01-16 07:03:56 -070034 int ret;
35
36 debug("%s starting\n", __func__);
37 ret = spl_init();
38 if (ret) {
39 debug("%s: spl_init() failed\n", __func__);
40 return ret;
41 }
Simon Glass7cf5fe02019-05-02 10:52:12 -060042#ifdef CONFIG_TPL
43 /* Do a mini-init if TPL has already done the full init */
44 ret = x86_cpu_reinit_f();
45#else
Simon Glass030777d2017-01-16 07:03:56 -070046 ret = arch_cpu_init();
Simon Glass7cf5fe02019-05-02 10:52:12 -060047#endif
Simon Glass030777d2017-01-16 07:03:56 -070048 if (ret) {
49 debug("%s: arch_cpu_init() failed\n", __func__);
50 return ret;
51 }
Simon Glass7cf5fe02019-05-02 10:52:12 -060052#ifndef CONFIG_TPL
Simon Glass030777d2017-01-16 07:03:56 -070053 ret = arch_cpu_init_dm();
54 if (ret) {
55 debug("%s: arch_cpu_init_dm() failed\n", __func__);
56 return ret;
57 }
Simon Glass7cf5fe02019-05-02 10:52:12 -060058#endif
Simon Glass6b19b4d2017-03-19 12:59:21 -060059 preloader_console_init();
Simon Glass7cf5fe02019-05-02 10:52:12 -060060#ifndef CONFIG_TPL
Simon Glass030777d2017-01-16 07:03:56 -070061 ret = print_cpuinfo();
62 if (ret) {
63 debug("%s: print_cpuinfo() failed\n", __func__);
64 return ret;
65 }
Simon Glass7cf5fe02019-05-02 10:52:12 -060066#endif
Simon Glass030777d2017-01-16 07:03:56 -070067 ret = dram_init();
68 if (ret) {
69 debug("%s: dram_init() failed\n", __func__);
70 return ret;
71 }
Simon Glass7cf5fe02019-05-02 10:52:12 -060072 if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) {
73 ret = mrccache_spl_save();
74 if (ret)
75 debug("%s: Failed to write to mrccache (err=%d)\n",
76 __func__, ret);
77 }
78
79#ifndef CONFIG_TPL
Simon Glass030777d2017-01-16 07:03:56 -070080 memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start);
81
82 /* TODO(sjg@chromium.org): Consider calling cpu_init_r() here */
83 ret = interrupt_init();
84 if (ret) {
85 debug("%s: interrupt_init() failed\n", __func__);
86 return ret;
87 }
88
89 /*
90 * The stack grows down from ptr. Put the global data at ptr. This
91 * will only be used for SPL. Once SPL loads U-Boot proper it will
92 * set up its own stack.
93 */
94 gd->new_gd = (struct global_data *)ptr;
95 memcpy(gd->new_gd, gd, sizeof(*gd));
96 arch_setup_gd(gd->new_gd);
97 gd->start_addr_sp = (ulong)ptr;
98
99 /* Cache the SPI flash. Otherwise copying the code to RAM takes ages */
100 ret = mtrr_add_request(MTRR_TYPE_WRBACK,
101 (1ULL << 32) - CONFIG_XIP_ROM_SIZE,
102 CONFIG_XIP_ROM_SIZE);
103 if (ret) {
Simon Glass7cf5fe02019-05-02 10:52:12 -0600104 debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret);
Simon Glass030777d2017-01-16 07:03:56 -0700105 return ret;
106 }
Simon Glass7cf5fe02019-05-02 10:52:12 -0600107 mtrr_commit(true);
108#endif
Simon Glass030777d2017-01-16 07:03:56 -0700109
110 return 0;
111}
112
113void board_init_f(ulong flags)
114{
115 int ret;
116
117 ret = x86_spl_init();
118 if (ret) {
119 debug("Error %d\n", ret);
120 hang();
121 }
Simon Glass7cf5fe02019-05-02 10:52:12 -0600122#ifdef CONFIG_TPL
123 gd->bd = malloc(sizeof(*gd->bd));
124 if (!gd->bd) {
125 printf("Out of memory for bd_info size %x\n", sizeof(*gd->bd));
126 hang();
127 }
128 board_init_r(gd, 0);
129#else
Simon Glass030777d2017-01-16 07:03:56 -0700130 /* Uninit CAR and jump to board_init_f_r() */
131 board_init_f_r_trampoline(gd->start_addr_sp);
Simon Glass7cf5fe02019-05-02 10:52:12 -0600132#endif
Simon Glass030777d2017-01-16 07:03:56 -0700133}
134
135void board_init_f_r(void)
136{
137 init_cache_f_r();
138 gd->flags &= ~GD_FLG_SERIAL_READY;
139 debug("cache status %d\n", dcache_status());
140 board_init_r(gd, 0);
141}
142
143u32 spl_boot_device(void)
144{
145 return BOOT_DEVICE_BOARD;
146}
147
148int spl_start_uboot(void)
149{
150 return 0;
151}
152
153void spl_board_announce_boot_device(void)
154{
155 printf("SPI flash");
156}
157
158static int spl_board_load_image(struct spl_image_info *spl_image,
159 struct spl_boot_device *bootdev)
160{
161 spl_image->size = CONFIG_SYS_MONITOR_LEN;
162 spl_image->entry_point = CONFIG_SYS_TEXT_BASE;
163 spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
164 spl_image->os = IH_OS_U_BOOT;
165 spl_image->name = "U-Boot";
166
167 debug("Loading to %lx\n", spl_image->load_addr);
168
169 return 0;
170}
171SPL_LOAD_IMAGE_METHOD("SPI", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
172
173int spl_spi_load_image(void)
174{
175 return -EPERM;
176}
177
Simon Glass7cf5fe02019-05-02 10:52:12 -0600178#ifdef CONFIG_X86_RUN_64BIT
Simon Glass030777d2017-01-16 07:03:56 -0700179void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
180{
181 int ret;
182
183 printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
184 ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
185 debug("ret=%d\n", ret);
186 while (1)
187 ;
188}
Simon Glass7cf5fe02019-05-02 10:52:12 -0600189#endif
190
191void spl_board_init(void)
192{
193#ifndef CONFIG_TPL
194 preloader_console_init();
195#endif
196}