Merge tag 'v2022.04-rc4' into next
[platform/kernel/u-boot.git] / arch / x86 / lib / tpl.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2018 Google, Inc
4  */
5
6 #include <common.h>
7 #include <debug_uart.h>
8 #include <dm.h>
9 #include <hang.h>
10 #include <image.h>
11 #include <init.h>
12 #include <log.h>
13 #include <spl.h>
14 #include <asm/cpu.h>
15 #include <asm/global_data.h>
16 #include <asm/mtrr.h>
17 #include <asm/processor.h>
18 #include <asm-generic/sections.h>
19
20 DECLARE_GLOBAL_DATA_PTR;
21
22 static int x86_tpl_init(void)
23 {
24         int ret;
25
26         debug("%s starting\n", __func__);
27         ret = x86_cpu_init_tpl();
28         if (ret) {
29                 debug("%s: x86_cpu_init_tpl() failed\n", __func__);
30                 return ret;
31         }
32         ret = spl_init();
33         if (ret) {
34                 debug("%s: spl_init() failed\n", __func__);
35                 return ret;
36         }
37         ret = arch_cpu_init();
38         if (ret) {
39                 debug("%s: arch_cpu_init() failed\n", __func__);
40                 return ret;
41         }
42         preloader_console_init();
43
44         return 0;
45 }
46
47 void board_init_f(ulong flags)
48 {
49         int ret;
50
51         ret = x86_tpl_init();
52         if (ret) {
53                 debug("Error %d\n", ret);
54                 panic("x86_tpl_init fail");
55         }
56
57         /* Uninit CAR and jump to board_init_f_r() */
58         board_init_r(gd, 0);
59 }
60
61 void board_init_f_r(void)
62 {
63         /* Not used since we never call board_init_f_r_trampoline() */
64         while (1);
65 }
66
67 u32 spl_boot_device(void)
68 {
69         return IS_ENABLED(CONFIG_CHROMEOS_VBOOT) ? BOOT_DEVICE_CROS_VBOOT :
70                 BOOT_DEVICE_SPI_MMAP;
71 }
72
73 int spl_start_uboot(void)
74 {
75         return 0;
76 }
77
78 void spl_board_announce_boot_device(void)
79 {
80         printf("SPI flash");
81 }
82
83 static int spl_board_load_image(struct spl_image_info *spl_image,
84                                 struct spl_boot_device *bootdev)
85 {
86         spl_image->size = CONFIG_SYS_MONITOR_LEN;  /* We don't know SPL size */
87         spl_image->entry_point = CONFIG_SPL_TEXT_BASE;
88         spl_image->load_addr = CONFIG_SPL_TEXT_BASE;
89         spl_image->os = IH_OS_U_BOOT;
90         spl_image->name = "U-Boot";
91
92         debug("Loading to %lx\n", spl_image->load_addr);
93
94         return 0;
95 }
96 SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image);
97
98 int spl_spi_load_image(void)
99 {
100         return -EPERM;
101 }
102
103 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
104 {
105         debug("Jumping to %s at %lx\n", spl_phase_name(spl_next_phase()),
106               (ulong)spl_image->entry_point);
107 #ifdef DEBUG
108         print_buffer(spl_image->entry_point, (void *)spl_image->entry_point, 1,
109                      0x20, 0);
110 #endif
111         jump_to_spl(spl_image->entry_point);
112         hang();
113 }
114
115 void spl_board_init(void)
116 {
117         preloader_console_init();
118 }
119
120 #if !CONFIG_IS_ENABLED(PCI)
121 /*
122  * This is a fake PCI bus for TPL when it doesn't have proper PCI. It is enough
123  * to bind the devices on the PCI bus, some of which have early-regs properties
124  * providing fixed BARs. Individual drivers program these BARs themselves so
125  * that they can access the devices. The BARs are allocated statically in the
126  * device tree.
127  *
128  * Once SPL is running it enables PCI properly, but does not auto-assign BARs
129  * for devices, so the TPL BARs continue to be used. Once U-Boot starts it does
130  * the auto allocation (after relocation).
131  */
132 #if CONFIG_IS_ENABLED(OF_REAL)
133 static const struct udevice_id tpl_fake_pci_ids[] = {
134         { .compatible = "pci-x86" },
135         { }
136 };
137 #endif
138
139 U_BOOT_DRIVER(pci_x86) = {
140         .name   = "pci_x86",
141         .id     = UCLASS_SIMPLE_BUS,
142         .of_match = of_match_ptr(tpl_fake_pci_ids),
143         DM_PHASE(tpl)
144 };
145 #endif