1.. SPDX-License-Identifier: GPL-2.0+
2.. sectionauthor:: Simon Glass <sjg@chromium.org>
3
4Chromebook Coral
5================
6
7Coral is a Chromebook (or really about 20 different Chromebooks) which use the
8Intel Apollo Lake platform (APL). The 'reef' Chromebooks use the same APL SoC so
9should also work. Some later ones based on Glacier Lake (GLK) need various
10changes in GPIOs, etc. but are very similar.
11
12It is hoped that this port can enable ports to embedded APL boards which are
13starting to appear.
14
15Note that booting U-Boot on APL is already supported by coreboot and
16Slim Bootloader. This documentation refers to a 'bare metal' port.
17
18
19Boot flow - TPL
20---------------
21
22Apollo Lake boots via an IFWI (Integrated Firmware Image). TPL is placed in
23this, in the IBBL entry.
24
25On boot, an on-chip microcontroller called the CSE (Converged Security Engine)
26sets up some SDRAM at ffff8000 and loads the TPL image to that address. The
27SRAM extends up to the top of 32-bit address space, but the last 2KB is the
28start16 region, so the TPL image must be 30KB at most, and CONFIG_TPL_TEXT_BASE
29must be ffff8000. Actually the start16 region is small and it could probably
30move from f800 to fe00, providing another 1.5KB, but TPL is only about 19KB so
31there is no need to change it at present. The size limit is enforced by
32CONFIG_TPL_SIZE_LIMIT to avoid producing images that won't boot.
33
34TPL (running from start.S) first sets up CAR (Cache-as-RAM) which provides
35larger area of RAM for use while booting. CAR is mapped at CONFIG_SYS_CAR_ADDR
36(fef00000) and is 768KB in size. It then sets up the stack in the botttom 64KB
37of this space (i.e. below fef10000). This means that the stack and early
38malloc() region in TPL can be 64KB at most.
39
40TPL operates without CONFIG_TPL_PCI enabled so PCI config access must use the
41x86-specific functions pci_x86_write_config(), etc. SPL creates a simple-bus
42device so that PCI devices are bound by driver model. Then arch_cpu_init_tpl()
43is called to early init on various devices. This includes placing PCI devices
44at hard-coded addresses in the memory map. PCI auto-config is not used.
45
46Most of the 16KB ROM is mapped into the very top of memory, except for the
47Intel descriptor (first 4KB) and the space for SRAM as above.
48
49TPL does not set up a bloblist since at present it does not have anything to
50pass to SPL.
51
52Once TPL is done it loads SPL from ROM using either the memory-mapped SPI or by
53using the Intel fast SPI driver. SPL is loaded into CAR, at the address given
54by CONFIG_SPL_TEXT_BASE, which is normally fef10000.
55
56Note that booting using the SPI driver results in an TPL image that is about
5726KB in size instead of 19KB. Also boot speed is worse by about 340ms. If you
58really want to use the driver, enable CONFIG_APL_SPI_FLASH_BOOT and set
59BOOT_FROM_FAST_SPI_FLASH to true[2].
60
61
62Boot flow - SPL
63---------------
64
65SPL (running from start_from_tpl.S) continues to use the same stack as TPL.
66It calls arch_cpu_init_spl() to set up a few devices, then init_dram() loads
67the FSP-M binary into CAR and runs to, to set up SDRAM. The address of the
68output 'HOB' list (Hand-off-block) is stored into gd->arch.hob_list for parsing.
69There is a 2GB chunk of SDRAM starting at 0 and the rest is at 4GB.
70
71PCI auto-config is not used in SPL either, but CONFIG_SPL_PCI is defined, so
72proper PCI access is available and normal dm_pci_read_config() calls can be
73used. However PCI auto-config is not used so the same static memory mapping set
74up by TPL is still active.
75
76SPL on x86 always runs with CONFIG_SPL_SEPARATE_BSS=y and BSS is at 120000
77(see u-boot-spl.lds). This works because SPL doesn't access BSS until after
78board_init_r(), as per the rules, and DRAM is available then.
79
80SPL sets up a bloblist and passes the SPL hand-off information to U-Boot proper.
81This includes a pointer to the HOB list as well as DRAM information. See
82struct arch_spl_handoff. The bloblist address is set by CONFIG_BLOBLIST_ADDR,
83normally 100000.
84
85SPL uses SPI flash to update the MRC caches in ROM. This speeds up subsequent
86boots. Be warned that SPL can take 30 seconds without this cache! This is a
87known issue with Intel SoCs with modern DRAM and apparently cannot be improved.
88The MRC caches are used to work around this.
89
90Once SPL is finished it loads U-Boot into SDRAM at CONFIG_SYS_TEXT_BASE, which
91is normally 1110000. Note that CAR is still active.
92
93
94Boot flow - U-Boot pre-relocation
95---------------------------------
96
97U-Boot (running from start_from_spl.S) starts running in RAM and uses the same
98stack as SPL. It does various init activities before relocation. Notably
99arch_cpu_init_dm() sets up the pin muxing for the chip using a very large table
100in the device tree.
101
102PCI auto-config is not used before relocation, but CONFIG_PCI of course is
103defined, so proper PCI access is available. The same static memory mapping set
104up by TPL is still active until relocation.
105
106As per usual, U-Boot allocates memory at the top of available RAM (a bit below
1072GB in this case) and copies things there ready to relocate itself. Notably
108reserve_arch() does not reserve space for the HOB list returned by FSP-M since
109this is already located in RAM.
110
111U-Boot then shuts down CAR and jumps to its relocated version.
112
113
114Boot flow - U-Boot post-relocation
115----------------------------------
116
117U-Boot starts up normally, running near the top of RAM. After driver model is
118running, arch_fsp_init_r() is called which loads and runs the FSP-S binary.
119This updates the HOB list to include graphics information, used by the fsp_video
120driver.
121
122PCI autoconfig is done and a few devices are probed to complete init. Most
123others are started only when they are used.
124
125Note that FSP-S is supposed to run after CAR has been shut down, which happens
126immediately before U-Boot starts up in its relocated position. Therefore we
127cannot run FSP-S before relocation. On the other hand we must run it before
128PCI auto-config is done, since FSP-S may show or hide devices. The first device
129that probes PCI after relocation is the serial port, in initr_serial(), so FSP-S
130must run before that. A corollary is that loading FSP-S must be done without
131using the SPI driver, to avoid probing PCI and causing an autoconfig, so
132memory-mapped reading is always used for FSP-S.
133
134It would be possible to tear down CAR in SPL instead of U-Boot. The SPL handoff
135information could make sure it does not include any pointers into CAR (in fact
136it doesn't). But tearing down CAR in U-Boot allows the initial state used by TPL
137and SPL to be read by U-Boot, which seems useful. It also matches how older
138platforms start up (those that don't use SPL).
139
140
141Performance
142-----------
143
144Bootstage is used through all phases of U-Boot to keep accurate timimgs for
145boot. Use 'bootstage report' in U-Boot to see the report, e.g.::
146
147    Timer summary in microseconds (16 records):
148           Mark    Elapsed  Stage
149              0          0  reset
150        155,325    155,325  TPL
151        204,014     48,689  end TPL
152        204,385        371  SPL
153        738,633    534,248  end SPL
154        739,161        528  board_init_f
155        842,764    103,603  board_init_r
156      1,166,233    323,469  main_loop
157      1,166,283         50  id=175
158
159    Accumulated time:
160                        62  fast_spi
161                       202  dm_r
162                     7,779  dm_spl
163                    15,555  dm_f
164                   208,357  fsp-m
165                   239,847  fsp-s
166                   292,143  mmap_spi
167
168CPU performance is about 3500 DMIPS::
169
170    => dhry
171    1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
172
173
174Partial memory map
175------------------
176
177::
178
179    ffffffff       Top of ROM (and last byte of 32-bit address space)
180    ffff8000       TPL loaded here (from IFWI)
181    ff000000       Bottom of ROM
182    fefc0000       Top of CAR region
183    fef96000       Stack for FSP-M
184    fef40000 59000 FSP-M
185    fef11000       SPL loaded here
186    fef10000       CONFIG_BLOBLIST_ADDR
187    fef10000       Stack top in TPL, SPL and U-Boot before relocation
188    fef00000  1000 CONFIG_BOOTSTAGE_STASH_ADDR
189    fef00000       Base of CAR region
190
191       30000       AP_DEFAULT_BASE (used to start up additional CPUs)
192       f0000       CONFIG_ROM_TABLE_ADDR
193      120000       BSS (defined in u-boot-spl.lds)
194      200000       FSP-S (which is run after U-Boot is relocated)
195     1110000       CONFIG_SYS_TEXT_BASE
196
197
198Supported peripherals
199---------------------
200
201- UART
202- SPI flash
203- Video
204- MMC (dev 0) and micro-SD (dev 1)
205- Chrome OS EC
206- Keyboard
207- USB
208
209
210To do
211-----
212
213- Finish peripherals
214   - left-side USB
215   - USB-C
216   - Cr50 (security chip: a basic driver is running but not included here)
217   - Sound (Intel I2S support exists, but need da7219 driver)
218   - Various minor features supported by LPC, etc.
219- Booting Chrome OS, e.g. with verified boot
220- Integrate with Chrome OS vboot
221- Improvements to booting from coreboot (i.e. as a coreboot target)
222- Use FSP-T binary instead of our own CAR implementation
223- Use the official FSP package instead of the coreboot one
224- Enable all CPU cores
225- Suspend / resume
226- ACPI
227
228
229Credits
230-------
231
232This is a spare-time project conducted slowly over a long period of time.
233
234Much of the code for this port came from Coreboot, an open-source firmware
235project similar to U-Boot's SPL in terms of features.
236
237Also see [2] for information about the boot flow used by coreboot. It is
238similar, but has an extra postcar stage. U-Boot doesn't need this since it
239supports relocating itself in memory.
240
241
242[2] Intel PDF https://www.coreboot.org/images/2/23/Apollolake_SoC.pdf
243