1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016 Google, Inc
4  */
5 
6 #include <common.h>
7 #include <cpu_func.h>
8 #include <debug_uart.h>
9 #include <dm.h>
10 #include <hang.h>
11 #include <image.h>
12 #include <init.h>
13 #include <irq_func.h>
14 #include <log.h>
15 #include <malloc.h>
16 #include <spl.h>
17 #include <syscon.h>
18 #include <asm/cpu.h>
19 #include <asm/cpu_common.h>
20 #include <asm/global_data.h>
21 #include <asm/mrccache.h>
22 #include <asm/mtrr.h>
23 #include <asm/pci.h>
24 #include <asm/processor.h>
25 #include <asm/spl.h>
26 #include <asm-generic/sections.h>
27 
28 DECLARE_GLOBAL_DATA_PTR;
29 
arch_cpu_init_dm(void)30 __weak int arch_cpu_init_dm(void)
31 {
32 	return 0;
33 }
34 
35 #ifdef CONFIG_TPL
36 
set_max_freq(void)37 static int set_max_freq(void)
38 {
39 	if (cpu_get_burst_mode_state() == BURST_MODE_UNAVAILABLE) {
40 		/*
41 		 * Burst Mode has been factory-configured as disabled and is not
42 		 * available in this physical processor package
43 		 */
44 		debug("Burst Mode is factory-disabled\n");
45 		return -ENOENT;
46 	}
47 
48 	/* Enable burst mode */
49 	cpu_set_burst_mode(true);
50 
51 	/* Enable speed step */
52 	cpu_set_eist(true);
53 
54 	/* Set P-State ratio */
55 	cpu_set_p_state_to_turbo_ratio();
56 
57 	return 0;
58 }
59 #endif
60 
x86_spl_init(void)61 static int x86_spl_init(void)
62 {
63 #ifndef CONFIG_TPL
64 	/*
65 	 * TODO(sjg@chromium.org): We use this area of RAM for the stack
66 	 * and global_data in SPL. Once U-Boot starts up and releocates it
67 	 * is not needed. We could make this a CONFIG option or perhaps
68 	 * place it immediately below CONFIG_SYS_TEXT_BASE.
69 	 */
70 	__maybe_unused char *ptr = (char *)0x110000;
71 #else
72 	struct udevice *punit;
73 #endif
74 	int ret;
75 
76 	debug("%s starting\n", __func__);
77 	if (IS_ENABLED(TPL))
78 		ret = x86_cpu_reinit_f();
79 	else
80 		ret = x86_cpu_init_f();
81 	ret = spl_init();
82 	if (ret) {
83 		debug("%s: spl_init() failed\n", __func__);
84 		return ret;
85 	}
86 	ret = arch_cpu_init();
87 	if (ret) {
88 		debug("%s: arch_cpu_init() failed\n", __func__);
89 		return ret;
90 	}
91 #ifndef CONFIG_TPL
92 	ret = arch_cpu_init_dm();
93 	if (ret) {
94 		debug("%s: arch_cpu_init_dm() failed\n", __func__);
95 		return ret;
96 	}
97 #endif
98 	preloader_console_init();
99 #ifndef CONFIG_TPL
100 	ret = print_cpuinfo();
101 	if (ret) {
102 		debug("%s: print_cpuinfo() failed\n", __func__);
103 		return ret;
104 	}
105 #endif
106 	ret = dram_init();
107 	if (ret) {
108 		debug("%s: dram_init() failed\n", __func__);
109 		return ret;
110 	}
111 	if (IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)) {
112 		ret = mrccache_spl_save();
113 		if (ret)
114 			debug("%s: Failed to write to mrccache (err=%d)\n",
115 			      __func__, ret);
116 	}
117 
118 #ifndef CONFIG_SYS_COREBOOT
119 	memset(&__bss_start, 0, (ulong)&__bss_end - (ulong)&__bss_start);
120 # ifndef CONFIG_TPL
121 
122 	/* TODO(sjg@chromium.org): Consider calling cpu_init_r() here */
123 	ret = interrupt_init();
124 	if (ret) {
125 		debug("%s: interrupt_init() failed\n", __func__);
126 		return ret;
127 	}
128 
129 	/*
130 	 * The stack grows down from ptr. Put the global data at ptr. This
131 	 * will only be used for SPL. Once SPL loads U-Boot proper it will
132 	 * set up its own stack.
133 	 */
134 	gd->new_gd = (struct global_data *)ptr;
135 	memcpy(gd->new_gd, gd, sizeof(*gd));
136 	arch_setup_gd(gd->new_gd);
137 	gd->start_addr_sp = (ulong)ptr;
138 
139 	/* Cache the SPI flash. Otherwise copying the code to RAM takes ages */
140 	ret = mtrr_add_request(MTRR_TYPE_WRBACK,
141 			       (1ULL << 32) - CONFIG_XIP_ROM_SIZE,
142 			       CONFIG_XIP_ROM_SIZE);
143 	if (ret) {
144 		debug("%s: SPI cache setup failed (err=%d)\n", __func__, ret);
145 		return ret;
146 	}
147 	mtrr_commit(true);
148 # else
149 	ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit);
150 	if (ret)
151 		debug("Could not find PUNIT (err=%d)\n", ret);
152 
153 	ret = set_max_freq();
154 	if (ret)
155 		debug("Failed to set CPU frequency (err=%d)\n", ret);
156 # endif
157 #endif
158 
159 	return 0;
160 }
161 
board_init_f(ulong flags)162 void board_init_f(ulong flags)
163 {
164 	int ret;
165 
166 	ret = x86_spl_init();
167 	if (ret) {
168 		printf("x86_spl_init: error %d\n", ret);
169 		hang();
170 	}
171 #if IS_ENABLED(CONFIG_TPL) || IS_ENABLED(CONFIG_SYS_COREBOOT)
172 	gd->bd = malloc(sizeof(*gd->bd));
173 	if (!gd->bd) {
174 		printf("Out of memory for bd_info size %x\n", sizeof(*gd->bd));
175 		hang();
176 	}
177 	board_init_r(gd, 0);
178 #else
179 	/* Uninit CAR and jump to board_init_f_r() */
180 	board_init_f_r_trampoline(gd->start_addr_sp);
181 #endif
182 }
183 
board_init_f_r(void)184 void board_init_f_r(void)
185 {
186 	init_cache_f_r();
187 	gd->flags &= ~GD_FLG_SERIAL_READY;
188 	debug("cache status %d\n", dcache_status());
189 	board_init_r(gd, 0);
190 }
191 
spl_boot_device(void)192 u32 spl_boot_device(void)
193 {
194 	return BOOT_DEVICE_SPI_MMAP;
195 }
196 
spl_start_uboot(void)197 int spl_start_uboot(void)
198 {
199 	return 0;
200 }
201 
spl_board_announce_boot_device(void)202 void spl_board_announce_boot_device(void)
203 {
204 	printf("SPI flash");
205 }
206 
spl_board_load_image(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)207 static int spl_board_load_image(struct spl_image_info *spl_image,
208 				struct spl_boot_device *bootdev)
209 {
210 	spl_image->size = CONFIG_SYS_MONITOR_LEN;
211 	spl_image->entry_point = CONFIG_SYS_TEXT_BASE;
212 	spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
213 	spl_image->os = IH_OS_U_BOOT;
214 	spl_image->name = "U-Boot";
215 
216 	if (!IS_ENABLED(CONFIG_SYS_COREBOOT)) {
217 		/*
218 		 * Copy U-Boot from ROM
219 		 * TODO(sjg@chromium.org): Figure out a way to get the text base
220 		 * correctly here, and in the device-tree binman definition.
221 		 *
222 		 * Also consider using FIT so we get the correct image length
223 		 * and parameters.
224 		 */
225 		memcpy((char *)spl_image->load_addr, (char *)0xfff00000,
226 		       0x100000);
227 	}
228 
229 	debug("Loading to %lx\n", spl_image->load_addr);
230 
231 	return 0;
232 }
233 SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image);
234 
spl_spi_load_image(void)235 int spl_spi_load_image(void)
236 {
237 	return -EPERM;
238 }
239 
240 #ifdef CONFIG_X86_RUN_64BIT
jump_to_image_no_args(struct spl_image_info * spl_image)241 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
242 {
243 	int ret;
244 
245 	printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
246 	ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
247 	debug("ret=%d\n", ret);
248 	hang();
249 }
250 #endif
251 
spl_board_init(void)252 void spl_board_init(void)
253 {
254 #ifndef CONFIG_TPL
255 	preloader_console_init();
256 #endif
257 }
258