common: Move some cache and MMU functions out of common.h
[oweals/u-boot.git] / arch / x86 / lib / spl.c
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(sjg@chromium.org): 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(sjg@chromium.org): 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 }