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