summaryrefslogtreecommitdiffstats
path: root/arch/x86/lib/tpl.c
blob: ac265b67449b1f902f5eb51d4b60dbd622a4f737 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2018 Google, Inc
 */

#include <common.h>
#include <debug_uart.h>
#include <dm.h>
#include <hang.h>
#include <image.h>
#include <init.h>
#include <spl.h>
#include <asm/cpu.h>
#include <asm/mtrr.h>
#include <asm/processor.h>
#include <asm-generic/sections.h>

DECLARE_GLOBAL_DATA_PTR;

__weak int arch_cpu_init_dm(void)
{
	return 0;
}

static int x86_tpl_init(void)
{
	int ret;

	debug("%s starting\n", __func__);
	ret = x86_cpu_init_tpl();
	if (ret) {
		debug("%s: x86_cpu_init_tpl() failed\n", __func__);
		return ret;
	}
	ret = spl_init();
	if (ret) {
		debug("%s: spl_init() failed\n", __func__);
		return ret;
	}
	ret = arch_cpu_init();
	if (ret) {
		debug("%s: arch_cpu_init() failed\n", __func__);
		return ret;
	}
	ret = arch_cpu_init_dm();
	if (ret) {
		debug("%s: arch_cpu_init_dm() failed\n", __func__);
		return ret;
	}
	preloader_console_init();

	return 0;
}

void board_init_f(ulong flags)
{
	int ret;

	ret = x86_tpl_init();
	if (ret) {
		debug("Error %d\n", ret);
		panic("x86_tpl_init fail");
	}

	/* Uninit CAR and jump to board_init_f_r() */
	board_init_r(gd, 0);
}

void board_init_f_r(void)
{
	/* Not used since we never call board_init_f_r_trampoline() */
	while (1);
}

u32 spl_boot_device(void)
{
	return IS_ENABLED(CONFIG_CHROMEOS) ? BOOT_DEVICE_CROS_VBOOT :
		BOOT_DEVICE_SPI_MMAP;
}

int spl_start_uboot(void)
{
	return 0;
}

void spl_board_announce_boot_device(void)
{
	printf("SPI flash");
}

static int spl_board_load_image(struct spl_image_info *spl_image,
				struct spl_boot_device *bootdev)
{
	spl_image->size = CONFIG_SYS_MONITOR_LEN;  /* We don't know SPL size */
	spl_image->entry_point = CONFIG_SPL_TEXT_BASE;
	spl_image->load_addr = CONFIG_SPL_TEXT_BASE;
	spl_image->os = IH_OS_U_BOOT;
	spl_image->name = "U-Boot";

	debug("Loading to %lx\n", spl_image->load_addr);

	return 0;
}
SPL_LOAD_IMAGE_METHOD("SPI", 5, BOOT_DEVICE_SPI_MMAP, spl_board_load_image);

int spl_spi_load_image(void)
{
	return -EPERM;
}

void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
{
	debug("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point);
	jump_to_spl(spl_image->entry_point);
	hang();
}

void spl_board_init(void)
{
	preloader_console_init();
}

#if !CONFIG_IS_ENABLED(PCI)
/*
 * This is a fake PCI bus for TPL when it doesn't have proper PCI. It is enough
 * to bind the devices on the PCI bus, some of which have early-regs properties
 * providing fixed BARs. Individual drivers program these BARs themselves so
 * that they can access the devices. The BARs are allocated statically in the
 * device tree.
 *
 * Once SPL is running it enables PCI properly, but does not auto-assign BARs
 * for devices, so the TPL BARs continue to be used. Once U-Boot starts it does
 * the auto allocation (after relocation).
 */
static const struct udevice_id tpl_fake_pci_ids[] = {
	{ .compatible = "pci-x86" },
	{ }
};

U_BOOT_DRIVER(pci_x86) = {
	.name	= "pci_x86",
	.id	= UCLASS_SIMPLE_BUS,
	.of_match = tpl_fake_pci_ids,
};
#endif