| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442 |
- .. SPDX-License-Identifier: GPL-2.0+
- .. sectionauthor:: Simon Glass <sjg@chromium.org>
- Chromebook Coral
- ================
- Coral is a Chromebook (or really about 20 different Chromebooks) which use the
- Intel Apollo Lake platform (APL). The 'reef' Chromebooks use the same APL SoC so
- should also work. Some later ones based on Glacier Lake (GLK) need various
- changes in GPIOs, etc. but are very similar.
- It is hoped that this port can enable ports to embedded APL boards which are
- starting to appear.
- Note that booting U-Boot on APL is already supported by coreboot and
- Slim Bootloader. This documentation refers to a 'bare metal' port.
- Building
- --------
- First, you need the following binary blobs:
- * descriptor.bin - Intel flash descriptor
- * fitimage.bin - Base flash image structure
- * fsp_m.bin - FSP-M, for setting up SDRAM
- * fsp_s.bin - FSP-S, for setting up Silicon
- * vbt.bin - for setting up display
- These binaries do not seem to be available publicly. If you have a ROM image,
- such as santa.bin then you can do this::
- cbfstool santa.bin extract -n fspm.bin -f fsp-m.bin
- cbfstool santa.bin extract -n fsps.bin -f fsp-s.bin
- cbfstool santa.bin extract -n vbt-santa.bin -f vbt.bin
- mkdir tmp
- cd tmp
- dump_fmap -x ../santa.bin
- mv SI_DESC ../descriptor.bin
- mv IFWI ../fitimage.bin
- Put all of these files in `board/google/chromebook_coral` so they can be found
- by the build.
- To build::
- make O=/tmp/b/chromebook_coral chromebook_coral_defconfig
- make O=/tmp/b/chromebook_coral -s -j30 all
- That should produce `/tmp/b/chrombook_coral/u-boot.rom` which you can use with
- a Dediprog em100::
- em100 -s -c w25q128fw -d /tmp/b/chromebook_coral/u-boot.rom -r
- or you can use flashrom to write it to the board. If you do that, make sure you
- have a way to restore the old ROM without booting the board. Otherwise you may
- brick it. Having said that, you may find these instructions useful if you want
- to unbrick your device:
- https://chromium.googlesource.com/chromiumos/platform/ec/+/cr50_stab/docs/case_closed_debugging.md
- You can buy Suzy-Q from Sparkfun:
- https://chromium.googlesource.com/chromiumos/third_party/hdctools/+/main/docs/ccd.md#suzyq-suzyqable
- Note that it will hang at the SPL prompt for 21 seconds. When booting into
- Chrome OS it will always select developer mode, so will wipe anything you have
- on the device if you let it proceed. You have two seconds in U-Boot to stop the
- auto-boot prompt and several seconds at the 'developer wipe' screen to stop it
- wiping the disk.
- Here is the console output::
- U-Boot TPL 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700)
- Trying to boot from Mapped SPI
- U-Boot SPL 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700)
- Trying to boot from Mapped SPI
- U-Boot 2021.04-rc1-00128-g344eefcdfec-dirty (Feb 11 2021 - 20:13:08 -0700)
- CPU: Intel(R) Celeron(R) CPU N3450 @ 1.10GHz
- DRAM: 3.9 GiB
- MMC: sdmmc@1b,0: 1, emmc@1c,0: 2
- Video: 1024x768x32 @ b0000000
- Model: Google Coral
- Net: No ethernet found.
- SF: Detected w25q128fw with page size 256 Bytes, erase size 4 KiB, total 16 MiB
- Hit any key to stop autoboot: 0
- 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 noresume 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_
- Setup located at 00090000:
- ACPI RSDP addr : 7991f000
- E820: 14 entries
- Addr Size Type
- d0000000 1000000 <NULL>
- 0 a0000 RAM
- a0000 60000 Reserved
- 7b000000 800000 Reserved
- 7b800000 4800000 Reserved
- 7ac00000 400000 Reserved
- 100000 ff00000 RAM
- 10000000 2151000 Reserved
- 12151000 68aaf000 RAM
- 100000000 80000000 RAM
- e0000000 10000000 Reserved
- 7991bfd0 12e4030 Reserved
- d0000000 10000000 Reserved
- fed10000 8000 Reserved
- Setup sectors : 1e
- Root flags : 1
- Sys size : 63420
- RAM size : 0
- Video mode : ffff
- Root dev : 0
- Boot flag : 0
- Jump : 66eb
- Header : 53726448
- Kernel V2
- Version : 20d
- Real mode switch : 0
- Start sys : 1000
- Kernel version : 38cc
- @00003acc:
- Type of loader : 80
- U-Boot, version 0
- Load flags : 81
- : loaded-high can-use-heap
- Setup move size : 8000
- Code32 start : 100000
- Ramdisk image : 0
- Ramdisk size : 0
- Bootsect kludge : 0
- Heap end ptr : 8e00
- Ext loader ver : 0
- Ext loader type : 0
- Command line ptr : 99000
- 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 noresume i915.modeset=1 tpm_tis.force=1 tpm_tis.interrupts=0 nmi_watchdog=panic,lapic disablevmx=off
- Initrd addr max : 7fffffff
- Kernel alignment : 200000
- Relocatable kernel : 1
- Min alignment : 15
- : 200000
- Xload flags : 3
- : 64-bit-entry can-load-above-4gb
- Cmdline size : 7ff
- Hardware subarch : 0
- HW subarch data : 0
- Payload offset : 26e
- Payload length : 612045
- Setup data : 0
- Pref address : 1000000
- Init size : 1383000
- Handover offset : 0
- Starting kernel ...
- Timer summary in microseconds (17 records):
- Mark Elapsed Stage
- 0 0 reset
- 155,279 155,279 TPL
- 237,088 81,809 end phase
- 237,533 445 SPL
- 816,456 578,923 end phase
- 817,357 901 board_init_f
- 1,061,751 244,394 board_init_r
- 1,402,435 340,684 id=64
- 1,430,071 27,636 main_loop
- 5,532,057 4,101,986 start_kernel
- Accumulated time:
- 685 dm_r
- 2,817 fast_spi
- 33,095 dm_spl
- 52,468 dm_f
- 208,242 fsp-m
- 242,221 fsp-s
- 332,710 mmap_spi
- Boot flow - TPL
- ---------------
- Apollo Lake boots via an IFWI (Integrated Firmware Image). TPL is placed in
- this, in the IBBL entry.
- On boot, an on-chip microcontroller called the CSE (Converged Security Engine)
- sets up some SDRAM at ffff8000 and loads the TPL image to that address. The
- SRAM extends up to the top of 32-bit address space, but the last 2KB is the
- start16 region, so the TPL image must be 30KB at most, and CONFIG_TPL_TEXT_BASE
- must be ffff8000. Actually the start16 region is small and it could probably
- move from f800 to fe00, providing another 1.5KB, but TPL is only about 19KB so
- there is no need to change it at present. The size limit is enforced by
- CONFIG_TPL_SIZE_LIMIT to avoid producing images that won't boot.
- TPL (running from start.S) first sets up CAR (Cache-as-RAM) which provides
- larger area of RAM for use while booting. CAR is mapped at CONFIG_SYS_CAR_ADDR
- (fef00000) and is 768KB in size. It then sets up the stack in the botttom 64KB
- of this space (i.e. below fef10000). This means that the stack and early
- malloc() region in TPL can be 64KB at most.
- TPL operates without CONFIG_TPL_PCI enabled so PCI config access must use the
- x86-specific functions pci_x86_write_config(), etc. SPL creates a simple-bus
- device so that PCI devices are bound by driver model. Then arch_cpu_init_tpl()
- is called to early init on various devices. This includes placing PCI devices
- at hard-coded addresses in the memory map. PCI auto-config is not used.
- Most of the 16KB ROM is mapped into the very top of memory, except for the
- Intel descriptor (first 4KB) and the space for SRAM as above.
- TPL does not set up a bloblist since at present it does not have anything to
- pass to SPL.
- Once TPL is done it loads SPL from ROM using either the memory-mapped SPI or by
- using the Intel fast SPI driver. SPL is loaded into CAR, at the address given
- by CONFIG_SPL_TEXT_BASE, which is normally fef10000.
- Note that booting using the SPI driver results in an TPL image that is about
- 26KB in size instead of 19KB. Also boot speed is worse by about 340ms. If you
- really want to use the driver, enable CONFIG_APL_SPI_FLASH_BOOT and set
- BOOT_FROM_FAST_SPI_FLASH to true[2].
- Boot flow - SPL
- ---------------
- SPL (running from start_from_tpl.S) continues to use the same stack as TPL.
- It calls arch_cpu_init_spl() to set up a few devices, then init_dram() loads
- the FSP-M binary into CAR and runs to, to set up SDRAM. The address of the
- output 'HOB' list (Hand-off-block) is stored into gd->arch.hob_list for parsing.
- There is a 2GB chunk of SDRAM starting at 0 and the rest is at 4GB.
- PCI auto-config is not used in SPL either, but CONFIG_SPL_PCI is defined, so
- proper PCI access is available and normal dm_pci_read_config() calls can be
- used. However PCI auto-config is not used so the same static memory mapping set
- up by TPL is still active.
- SPL on x86 always runs with CONFIG_SPL_SEPARATE_BSS=y and BSS is at 120000
- (see u-boot-spl.lds). This works because SPL doesn't access BSS until after
- board_init_r(), as per the rules, and DRAM is available then.
- SPL sets up a bloblist and passes the SPL hand-off information to U-Boot proper.
- This includes a pointer to the HOB list as well as DRAM information. See
- struct arch_spl_handoff. The bloblist address is set by CONFIG_BLOBLIST_ADDR,
- normally 100000.
- SPL uses SPI flash to update the MRC caches in ROM. This speeds up subsequent
- boots. Be warned that SPL can take 30 seconds without this cache! This is a
- known issue with Intel SoCs with modern DRAM and apparently cannot be improved.
- The MRC caches are used to work around this.
- Once SPL is finished it loads U-Boot into SDRAM at CONFIG_TEXT_BASE, which
- is normally 1110000. Note that CAR is still active.
- Boot flow - U-Boot pre-relocation
- ---------------------------------
- U-Boot (running from start_from_spl.S) starts running in RAM and uses the same
- stack as SPL. It does various init activities before relocation. Notably
- fsp_setup_pinctrl() sets up the pin muxing for the chip using a very large table
- in the device tree.
- PCI auto-config is not used before relocation, but CONFIG_PCI of course is
- defined, so proper PCI access is available. The same static memory mapping set
- up by TPL is still active until relocation.
- As per usual, U-Boot allocates memory at the top of available RAM (a bit below
- 2GB in this case) and copies things there ready to relocate itself. Notably
- reserve_arch() does not reserve space for the HOB list returned by FSP-M since
- this is already located in RAM.
- U-Boot then shuts down CAR and jumps to its relocated version.
- Boot flow - U-Boot post-relocation
- ----------------------------------
- U-Boot starts up normally, running near the top of RAM. After driver model is
- running, arch_fsp_init_r() is called which loads and runs the FSP-S binary.
- This updates the HOB list to include graphics information, used by the fsp_video
- driver.
- PCI autoconfig is done and a few devices are probed to complete init. Most
- others are started only when they are used.
- Note that FSP-S is supposed to run after CAR has been shut down, which happens
- immediately before U-Boot starts up in its relocated position. Therefore we
- cannot run FSP-S before relocation. On the other hand we must run it before
- PCI auto-config is done, since FSP-S may show or hide devices. The first device
- that probes PCI after relocation is the serial port, in initr_serial(), so FSP-S
- must run before that. A corollary is that loading FSP-S must be done without
- using the SPI driver, to avoid probing PCI and causing an autoconfig, so
- memory-mapped reading is always used for FSP-S.
- It would be possible to tear down CAR in SPL instead of U-Boot. The SPL handoff
- information could make sure it does not include any pointers into CAR (in fact
- it doesn't). But tearing down CAR in U-Boot allows the initial state used by TPL
- and SPL to be read by U-Boot, which seems useful. It also matches how older
- platforms start up (those that don't use SPL).
- Performance
- -----------
- Bootstage is used through all phases of U-Boot to keep accurate timimgs for
- boot. Use 'bootstage report' in U-Boot to see the report, e.g.::
- Timer summary in microseconds (16 records):
- Mark Elapsed Stage
- 0 0 reset
- 155,325 155,325 TPL
- 204,014 48,689 end TPL
- 204,385 371 SPL
- 738,633 534,248 end SPL
- 739,161 528 board_init_f
- 842,764 103,603 board_init_r
- 1,166,233 323,469 main_loop
- 1,166,283 50 id=175
- Accumulated time:
- 62 fast_spi
- 202 dm_r
- 7,779 dm_spl
- 15,555 dm_f
- 208,357 fsp-m
- 239,847 fsp-s
- 292,143 mmap_spi
- CPU performance is about 3500 DMIPS::
- => dhry
- 1000000 iterations in 161 ms: 6211180/s, 3535 DMIPS
- Partial memory map
- ------------------
- ::
- ffffffff Top of ROM (and last byte of 32-bit address space)
- ffff8000 TPL loaded here (from IFWI)
- ff000000 Bottom of ROM
- fefc0000 Top of CAR region
- fef96000 Stack for FSP-M
- fef40000 59000 FSP-M (also VPL loads here)
- fef11000 SPL loaded here
- fef10000 CONFIG_BLOBLIST_ADDR
- fef10000 Stack top in TPL, SPL and U-Boot before relocation
- fef00000 1000 CONFIG_BOOTSTAGE_STASH_ADDR
- fef00000 Base of CAR region
- 30000 AP_DEFAULT_BASE (used to start up additional CPUs)
- f0000 CONFIG_ROM_TABLE_ADDR
- 120000 BSS (defined in u-boot-spl.lds)
- 200000 FSP-S (which is run after U-Boot is relocated)
- 1110000 CONFIG_TEXT_BASE
- Speeding up SPL for development
- -------------------------------
- The 21-second wait for memory training is annoying during development, since
- every new image incurs this cost when booting. There is no cache to fall back on
- since that area of the image is empty on start-up.
- You can add suitable cache contents to the image to fix this, for development
- purposes only, like this::
- # Read the image back after booting through SPL
- em100 -s -c w25q128fw -u image.bin
- # Extract the two cache regions
- binman extract -i image.bin extra *cache
- # Move them into the source directory
- mv *cache board/google/chromebook_coral
- Then add something like this to the devicetree::
- #if IS_ENABLED(CONFIG_HAVE_MRC) || IS_ENABLED(CONFIG_FSP_VERSION2)
- /* Provide initial contents of the MRC data for faster development */
- rw-mrc-cache {
- type = "blob";
- /* Mirror the offset in spi-flash@0 */
- offset = <0xff8e0000>;
- size = <0x10000>;
- filename = "board/google/chromebook_coral/rw-mrc-cache";
- };
- rw-var-mrc-cache {
- type = "blob";
- size = <0x1000>;
- filename = "board/google/chromebook_coral/rw-var-mrc-cache";
- };
- #endif
- This tells binman to put the cache contents in the same place as the
- `rw-mrc-cache` and `rw-var-mrc-cache` regions defined by the SPI-flash driver.
- Supported peripherals
- ---------------------
- The following have U-Boot drivers:
- - UART
- - SPI flash
- - Video
- - MMC (dev 0) and micro-SD (dev 1)
- - Chrome OS EC
- - Cr50 (security chip)
- - Keyboard
- - USB
- To do
- -----
- - Finish peripherals
- - Sound (Intel I2S support exists, but need da7219 driver)
- - Use FSP-T binary instead of our own CAR implementation
- - Use the official FSP package instead of the coreboot one
- - Suspend / resume
- - Fix MMC which seems to try to read even though the card is empty
- - Fix USB3 crash "WARN halted endpoint, queueing URB anyway."
- Credits
- -------
- This is a spare-time project conducted slowly over a long period of time.
- Much of the code for this port came from Coreboot, an open-source firmware
- project similar to U-Boot's SPL in terms of features.
- Also see [2] for information about the boot flow used by coreboot. It is
- similar, but has an extra postcar stage. U-Boot doesn't need this since it
- supports relocating itself in memory.
- [2] Intel PDF https://www.coreboot.org/images/2/23/Apollolake_SoC.pdf
|