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 19Building 20-------- 21 22First, you need the following binary blobs: 23 24 * descriptor.bin - Intel flash descriptor 25 * fitimage.bin - Base flash image structure 26 * fsp_m.bin - FSP-M, for setting up SDRAM 27 * fsp_s.bin - FSP-S, for setting up Silicon 28 * vbt.bin - for setting up display 29 30These binaries do not seem to be available publicly. If you have a ROM image, 31such as santa.bin then you can do this:: 32 33 cbfstool santa.bin extract -n fspm.bin -f fsp-m.bin 34 cbfstool santa.bin extract -n fsps.bin -f fsp-s.bin 35 cbfstool santa.bin extract -n vbt-santa.bin -f vbt.bin 36 mkdir tmp 37 cd tmp 38 dump_fmap -x ../santa.bin 39 mv SI_DESC ../descriptor.bin 40 mv IFWI ../fitimage.bin 41 42Put all of these files in `board/google/chromebook_coral` so they can be found 43by the build. 44 45To build:: 46 47 make O=/tmp/b/chromebook_coral chromebook_coral_defconfig 48 make O=/tmp/b/chromebook_coral -s -j30 all 49 50That should produce `/tmp/b/chrombook_coral/u-boot.rom` which you can use with 51a Dediprog em100:: 52 53 em100 -s -c w25q128fw -d /tmp/b/chromebook_coral/u-boot.rom -r 54 55or you can use flashrom to write it to the board. If you do that, make sure you 56have a way to restore the old ROM without booting the board. Otherwise you may 57brick it. Having said that, you may find these instructions useful if you want 58to unbrick your device: 59 60 https://chromium.googlesource.com/chromiumos/platform/ec/+/cr50_stab/docs/case_closed_debugging.md 61 62You can buy Suzy-Q from Sparkfun: 63 64 https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/main/docs/ccd.md#suzyq-suzyqable 65 66Note that it will hang at the SPL prompt for 21 seconds. When booting into 67Chrome OS it will always select developer mode, so will wipe anything you have 68on the device if you let it proceed. You have two seconds in U-Boot to stop the 69auto-boot prompt and several seconds at the 'developer wipe' screen to stop it 70wiping the disk. 71 72Here is the console output:: 73 74 U-Boot TPL 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700) 75 Trying to boot from Mapped SPI 76 77 U-Boot SPL 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700) 78 Trying to boot from Mapped SPI 79 80 81 U-Boot 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700) 82 83 CPU: Intel(R) Celeron(R) CPU N3450 @ 1.10GHz 84 DRAM: 3.9 GiB 85 MMC: sdmmc@1b,0: 1, emmc@1c,0: 2 86 Video: 1024x768x32 @ b0000000 87 Model: Google Coral 88 Net: No ethernet found. 89 SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB 90 Hit any key to stop autoboot: 0 91 cmdline=console= loglevel=7 init=/sbin/init cros_secure oops=panic panic=-1 root=PARTUUID=${uuid}/PARTNROFF=1 rootwait rw dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=0 dm="1 vroot none rw 1,0 3788800 verity payload=ROOT_DEV hashtree=HASH_DEV hashstart=3788800 alg=sha1 root_hexdigest=55052b629d3ac889f25a9583ea12cdcd3ea15ff8 salt=a2d4d9e574069f4fed5e3961b99054b7a4905414b60a25d89974a7334021165c" noinitrd vt.global_cursor_default=0 kern_guid=${uuid} add_efi_memmap boot=local noresume noswap i915.modeset=1 Kernel command line: "console= loglevel=7 init=/sbin/init cros_secure oops=panic panic=-1 root=PARTUUID=35c775e7-3735-d745-93e5-d9e0238f7ed0/PARTNROFF=1 rootwait rw dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=0 dm="1 vroot none rw 1,0 3788800 verity payload=ROOT_DEV hashtree=HASH_DEV hashstart=3788800 alg=sha1 root_hexdigest=55052b629d3ac889f25a9583ea12cdcd3ea15ff8 salt=a2d4d9e574069f4fed5e3961b99054b7a4905414b60a25d89974a7334021165c" noinitrd vt.global_cursor_default=0 kern_guid=35c775e7-3735-d745-93e5-d9e0238f7ed0 add_efi_memmap boot=local noresume noswap i915.modeset=1 tpm_tis.force=1 tpm_tis.interrupts=0 nmi_watchdog=panic,lapic disablevmx=off " 92 Setup located at 00090000: 93 94 ACPI RSDP addr : 7991f000 95 E820: 14 entries 96 Addr Size Type 97 d0000000 1000000 <NULL> 98 0 a0000 RAM 99 a0000 60000 Reserved 100 7b000000 800000 Reserved 101 7b800000 4800000 Reserved 102 7ac00000 400000 Reserved 103 100000 ff00000 RAM 104 10000000 2151000 Reserved 105 12151000 68aaf000 RAM 106 100000000 80000000 RAM 107 e0000000 10000000 Reserved 108 7991bfd0 12e4030 Reserved 109 d0000000 10000000 Reserved 110 fed10000 8000 Reserved 111 Setup sectors : 1e 112 Root flags : 1 113 Sys size : 63420 114 RAM size : 0 115 Video mode : ffff 116 Root dev : 0 117 Boot flag : 0 118 Jump : 66eb 119 Header : 53726448 120 Kernel V2 121 Version : 20d 122 Real mode switch : 0 123 Start sys : 1000 124 Kernel version : 38cc 125 @00003acc: 126 Type of loader : 80 127 U-Boot, version 0 128 Load flags : 81 129 : loaded-high can-use-heap 130 Setup move size : 8000 131 Code32 start : 100000 132 Ramdisk image : 0 133 Ramdisk size : 0 134 Bootsect kludge : 0 135 Heap end ptr : 8e00 136 Ext loader ver : 0 137 Ext loader type : 0 138 Command line ptr : 99000 139 console= loglevel=7 init=/sbin/init cros_secure oops=panic panic=-1 root=PARTUUID=35c775e7-3735-d745-93e5-d9e0238f7ed0/PARTNROFF=1 rootwait rw dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=0 dm="1 vroot none rw 1,0 3788800 verity payload=ROOT_DEV hashtree=HASH_DEV hashstart=3788800 alg=sha1 root_hexdigest=55052b629d3ac889f25a9583ea12cdcd3ea15ff8 salt=a2d4d9e574069f4fed5e3961b99054b7a4905414b60a25d89974a7334021165c" noinitrd vt.global_cursor_default=0 kern_guid=35c775e7-3735-d745-93e5-d9e0238f7ed0 add_efi_memmap boot=local noresume noswap i915.modeset=1 tpm_tis.force=1 tpm_tis.interrupts=0 nmi_watchdog=panic,lapic disablevmx=off 140 Initrd addr max : 7fffffff 141 Kernel alignment : 200000 142 Relocatable kernel : 1 143 Min alignment : 15 144 : 200000 145 Xload flags : 3 146 : 64-bit-entry can-load-above-4gb 147 Cmdline size : 7ff 148 Hardware subarch : 0 149 HW subarch data : 0 150 Payload offset : 26e 151 Payload length : 612045 152 Setup data : 0 153 Pref address : 1000000 154 Init size : 1383000 155 Handover offset : 0 156 157 Starting kernel ... 158 159 Timer summary in microseconds (17 records): 160 Mark Elapsed Stage 161 0 0 reset 162 155,279 155,279 TPL 163 237,088 81,809 end phase 164 237,533 445 SPL 165 816,456 578,923 end phase 166 817,357 901 board_init_f 167 1,061,751 244,394 board_init_r 168 1,402,435 340,684 id=64 169 1,430,071 27,636 main_loop 170 5,532,057 4,101,986 start_kernel 171 172 Accumulated time: 173 685 dm_r 174 2,817 fast_spi 175 33,095 dm_spl 176 52,468 dm_f 177 208,242 fsp-m 178 242,221 fsp-s 179 332,710 mmap_spi 180 181 182Boot flow - TPL 183--------------- 184 185Apollo Lake boots via an IFWI (Integrated Firmware Image). TPL is placed in 186this, in the IBBL entry. 187 188On boot, an on-chip microcontroller called the CSE (Converged Security Engine) 189sets up some SDRAM at ffff8000 and loads the TPL image to that address. The 190SRAM extends up to the top of 32-bit address space, but the last 2KB is the 191start16 region, so the TPL image must be 30KB at most, and CONFIG_TPL_TEXT_BASE 192must be ffff8000. Actually the start16 region is small and it could probably 193move from f800 to fe00, providing another 1.5KB, but TPL is only about 19KB so 194there is no need to change it at present. The size limit is enforced by 195CONFIG_TPL_SIZE_LIMIT to avoid producing images that won't boot. 196 197TPL (running from start.S) first sets up CAR (Cache-as-RAM) which provides 198larger area of RAM for use while booting. CAR is mapped at CONFIG_SYS_CAR_ADDR 199(fef00000) and is 768KB in size. It then sets up the stack in the botttom 64KB 200of this space (i.e. below fef10000). This means that the stack and early 201malloc() region in TPL can be 64KB at most. 202 203TPL operates without CONFIG_TPL_PCI enabled so PCI config access must use the 204x86-specific functions pci_x86_write_config(), etc. SPL creates a simple-bus 205device so that PCI devices are bound by driver model. Then arch_cpu_init_tpl() 206is called to early init on various devices. This includes placing PCI devices 207at hard-coded addresses in the memory map. PCI auto-config is not used. 208 209Most of the 16KB ROM is mapped into the very top of memory, except for the 210Intel descriptor (first 4KB) and the space for SRAM as above. 211 212TPL does not set up a bloblist since at present it does not have anything to 213pass to SPL. 214 215Once TPL is done it loads SPL from ROM using either the memory-mapped SPI or by 216using the Intel fast SPI driver. SPL is loaded into CAR, at the address given 217by CONFIG_SPL_TEXT_BASE, which is normally fef10000. 218 219Note that booting using the SPI driver results in an TPL image that is about 22026KB in size instead of 19KB. Also boot speed is worse by about 340ms. If you 221really want to use the driver, enable CONFIG_APL_SPI_FLASH_BOOT and set 222BOOT_FROM_FAST_SPI_FLASH to true[2]. 223 224 225Boot flow - SPL 226--------------- 227 228SPL (running from start_from_tpl.S) continues to use the same stack as TPL. 229It calls arch_cpu_init_spl() to set up a few devices, then init_dram() loads 230the FSP-M binary into CAR and runs to, to set up SDRAM. The address of the 231output 'HOB' list (Hand-off-block) is stored into gd->arch.hob_list for parsing. 232There is a 2GB chunk of SDRAM starting at 0 and the rest is at 4GB. 233 234PCI auto-config is not used in SPL either, but CONFIG_SPL_PCI is defined, so 235proper PCI access is available and normal dm_pci_read_config() calls can be 236used. However PCI auto-config is not used so the same static memory mapping set 237up by TPL is still active. 238 239SPL on x86 always runs with CONFIG_SPL_SEPARATE_BSS=y and BSS is at 120000 240(see u-boot-spl.lds). This works because SPL doesn't access BSS until after 241board_init_r(), as per the rules, and DRAM is available then. 242 243SPL sets up a bloblist and passes the SPL hand-off information to U-Boot proper. 244This includes a pointer to the HOB list as well as DRAM information. See 245struct arch_spl_handoff. The bloblist address is set by CONFIG_BLOBLIST_ADDR, 246normally 100000. 247 248SPL uses SPI flash to update the MRC caches in ROM. This speeds up subsequent 249boots. Be warned that SPL can take 30 seconds without this cache! This is a 250known issue with Intel SoCs with modern DRAM and apparently cannot be improved. 251The MRC caches are used to work around this. 252 253Once SPL is finished it loads U-Boot into SDRAM at CONFIG_SYS_TEXT_BASE, which 254is normally 1110000. Note that CAR is still active. 255 256 257Boot flow - U-Boot pre-relocation 258--------------------------------- 259 260U-Boot (running from start_from_spl.S) starts running in RAM and uses the same 261stack as SPL. It does various init activities before relocation. Notably 262arch_cpu_init_dm() sets up the pin muxing for the chip using a very large table 263in the device tree. 264 265PCI auto-config is not used before relocation, but CONFIG_PCI of course is 266defined, so proper PCI access is available. The same static memory mapping set 267up by TPL is still active until relocation. 268 269As per usual, U-Boot allocates memory at the top of available RAM (a bit below 2702GB in this case) and copies things there ready to relocate itself. Notably 271reserve_arch() does not reserve space for the HOB list returned by FSP-M since 272this is already located in RAM. 273 274U-Boot then shuts down CAR and jumps to its relocated version. 275 276 277Boot flow - U-Boot post-relocation 278---------------------------------- 279 280U-Boot starts up normally, running near the top of RAM. After driver model is 281running, arch_fsp_init_r() is called which loads and runs the FSP-S binary. 282This updates the HOB list to include graphics information, used by the fsp_video 283driver. 284 285PCI autoconfig is done and a few devices are probed to complete init. Most 286others are started only when they are used. 287 288Note that FSP-S is supposed to run after CAR has been shut down, which happens 289immediately before U-Boot starts up in its relocated position. Therefore we 290cannot run FSP-S before relocation. On the other hand we must run it before 291PCI auto-config is done, since FSP-S may show or hide devices. The first device 292that probes PCI after relocation is the serial port, in initr_serial(), so FSP-S 293must run before that. A corollary is that loading FSP-S must be done without 294using the SPI driver, to avoid probing PCI and causing an autoconfig, so 295memory-mapped reading is always used for FSP-S. 296 297It would be possible to tear down CAR in SPL instead of U-Boot. The SPL handoff 298information could make sure it does not include any pointers into CAR (in fact 299it doesn't). But tearing down CAR in U-Boot allows the initial state used by TPL 300and SPL to be read by U-Boot, which seems useful. It also matches how older 301platforms start up (those that don't use SPL). 302 303 304Performance 305----------- 306 307Bootstage is used through all phases of U-Boot to keep accurate timimgs for 308boot. Use 'bootstage report' in U-Boot to see the report, e.g.:: 309 310 Timer summary in microseconds (16 records): 311 Mark Elapsed Stage 312 0 0 reset 313 155,325 155,325 TPL 314 204,014 48,689 end TPL 315 204,385 371 SPL 316 738,633 534,248 end SPL 317 739,161 528 board_init_f 318 842,764 103,603 board_init_r 319 1,166,233 323,469 main_loop 320 1,166,283 50 id=175 321 322 Accumulated time: 323 62 fast_spi 324 202 dm_r 325 7,779 dm_spl 326 15,555 dm_f 327 208,357 fsp-m 328 239,847 fsp-s 329 292,143 mmap_spi 330 331CPU performance is about 3500 DMIPS:: 332 333 => dhry 334 1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS 335 336 337Partial memory map 338------------------ 339 340:: 341 342 ffffffff Top of ROM (and last byte of 32-bit address space) 343 ffff8000 TPL loaded here (from IFWI) 344 ff000000 Bottom of ROM 345 fefc0000 Top of CAR region 346 fef96000 Stack for FSP-M 347 fef40000 59000 FSP-M (also VPL loads here) 348 fef11000 SPL loaded here 349 fef10000 CONFIG_BLOBLIST_ADDR 350 fef10000 Stack top in TPL, SPL and U-Boot before relocation 351 fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR 352 fef00000 Base of CAR region 353 354 30000 AP_DEFAULT_BASE (used to start up additional CPUs) 355 f0000 CONFIG_ROM_TABLE_ADDR 356 120000 BSS (defined in u-boot-spl.lds) 357 200000 FSP-S (which is run after U-Boot is relocated) 358 1110000 CONFIG_SYS_TEXT_BASE 359 360 361Speeding up SPL for development 362------------------------------- 363 364The 21-second wait for memory training is annoying during development, since 365every new image incurs this cost when booting. There is no cache to fall back on 366since that area of the image is empty on start-up. 367 368You can add suitable cache contents to the image to fix this, for development 369purposes only, like this:: 370 371 # Read the image back after booting through SPL 372 em100 -s -c w25q128fw -u image.bin 373 374 # Extract the two cache regions 375 binman extract -i image.bin extra *cache 376 377 # Move them into the source directory 378 mv *cache board/google/chromebook_coral 379 380Then add something like this to the devicetree:: 381 382 #if IS_ENABLED(CONFIG_HAVE_MRC) || IS_ENABLED(CONFIG_FSP_VERSION2) 383 /* Provide initial contents of the MRC data for faster development */ 384 rw-mrc-cache { 385 type = "blob"; 386 /* Mirror the offset in spi-flash@0 */ 387 offset = <0xff8e0000>; 388 size = <0x10000>; 389 filename = "board/google/chromebook_coral/rw-mrc-cache"; 390 }; 391 rw-var-mrc-cache { 392 type = "blob"; 393 size = <0x1000>; 394 filename = "board/google/chromebook_coral/rw-var-mrc-cache"; 395 }; 396 #endif 397 398This tells binman to put the cache contents in the same place as the 399`rw-mrc-cache` and `rw-var-mrc-cache` regions defined by the SPI-flash driver. 400 401 402Supported peripherals 403--------------------- 404 405The following have U-Boot drivers: 406 407 - UART 408 - SPI flash 409 - Video 410 - MMC (dev 0) and micro-SD (dev 1) 411 - Chrome OS EC 412 - Cr50 (security chip) 413 - Keyboard 414 - USB 415 416 417To do 418----- 419 420- Finish peripherals 421 - Sound (Intel I2S support exists, but need da7219 driver) 422- Use FSP-T binary instead of our own CAR implementation 423- Use the official FSP package instead of the coreboot one 424- Suspend / resume 425- Fix MMC which seems to try to read even though the card is empty 426- Fix USB3 crash "WARN halted endpoint, queueing URB anyway." 427 428 429Credits 430------- 431 432This is a spare-time project conducted slowly over a long period of time. 433 434Much of the code for this port came from Coreboot, an open-source firmware 435project similar to U-Boot's SPL in terms of features. 436 437Also see [2] for information about the boot flow used by coreboot. It is 438similar, but has an extra postcar stage. U-Boot doesn't need this since it 439supports relocating itself in memory. 440 441 442[2] Intel PDF https://www.coreboot.org/images/2/23/Apollolake_SoC.pdf 443