git URL updates. Point out that the BCT may omit SDRAM configuration data.
This document explains the general structure of the Tegra BCT, or Boot Configuration Table.
The BCT is a data structure that provides basic system initialization parameters, and defines the bootloader to execute. The BCT contains:
Header information, such as cryptographic validation hashes and size information.
Boot memory configuration. This allows the boot memory controller to be programmed optimally, in order to read the bootloader.
SDRAM controller configuration. This allows the SDRAM controller to be programmed, and hence external SDRAM accessed.
A bad block table.
Information about the bootloader to execute.
A "customer data" area, which may be used to store arbitrary customer- or device-software-specific data. This area includes the ODMDATA.
The BCT contains a cryptographic hash of the overall BCT itself, and each individual copy of the bootloader. This allows the boot ROM to validate that the BCT, and later the bootloader, has been successfully located, and read from boot memory without corruption.
The algorithm used to generate the hash is AES-CMAC. A "zero" key is used by chips on developer/reference boards, and some production systems.
For this reason, whenever the bootloader is modified, the BCT must be re- generated and re-programmed, so that the bootloader hash is up-to-date.
The BCT contains space for four copies (known as "sets" or "parameter sets") of both the SDRAM and boot memory (or "device") configuration. Fuses and/or straps encode which set is used. This allows, for example, the same software image to be used across multiple builds of a board, each using a different SDRAM chip and/or boot memory configuration; the SDRAM chip and/or boot memory selection, and strap selection would be altered in tandem during the board manufacturing process to select the appropriate data set within the BCT.
If a particular board never uses fuse or strap values that would select a particular parameter set, there is no need to fill it in. It is common for only one set to be filled in, or for the same values to be duplicated into all sets.
Boot memory configuration
When reading the BCT, the relevant boot memory controller is programmed with conservative timings and/or uses a boot-specific protocol. The boot memory configuration in the BCT allows the controller to be reprogrammed with optimal timings and/or accessed using a more general-purpose protocol.
Tegra supports reading the BCT and bootloader from NAND, SPI flash, or eMMC/SD. For each of these device types, a different set of configuration information is required by the relevant device controller.
The NAND controller requires the clock divider value, a couple of device timing parameters, and block/page size parameters.
The SD/MMC controller requires the clock divider value, and data bus and device power class configuration. On Tegra30, multiple SD/MMC controllers are supported, so the device instance must be selected.
The SPI controller requires clock source and divider configuration, and a flag indicating whether normal or fast read operations should be performed.
For each boot memory configuration, there is also a field that defines which memory type it represents. This field is solely an error-check; the value in the BCT must match the memory type that the BCT was read from. In other words, it is not possible, for example, for the boot ROM to read the BCT from SPI flash, but then read the bootloader from eMMC.
Tegra does not support SPD for SDRAM identification, but rather expects that a specific size and configuration of memory device be attached. Equally, correct configuration of the memory controller requires careful qualification of an individual board design’s signal timing properties across a wide range of operating conditions. As such, some aspects of the SDRAM controller configuration may vary between boards using an identical SDRAM device.
Tegra’s SDRAM controller itself contains many registers that must be programmed based on the selected SDRAM device, and board-specific signal timing parameters. The clock controller must be programmed to provide the correct clock frequency to the SDRAM controller. The pinmux controller must be programmed for some aspects of SDRAM signal timing.
The BCT’s SDRAM configuration is mostly a raw dump of the registers, or fields within registers, that need to be programmed.
The BCT may choose to omit valid SDRAM configuration data if the bootloader is to be loaded into IRAM rather than SDRAM. If the bootloader needs access to SDRAM, it must program the SDRAM controller itself.
The BCT defines the location and size of the bootloader in boot memory, along with the intended load and execution address (typically in SDRAM), and a cryptographic validation hash.
The BCT contains four copies of bootloader information. This allows automatic fallback to the second or later copy of the bootloader, if present, if the first copy cannot be read, or the hash validation fails. The bootloader table search order is not influenced by the SDRAM/boot memory parameter set that is selected.
The BCT also contains a bad block table. This indicates which areas of the boot memory device are known to be bad. Any blocks listed in this table are automatically skipped when reading the bootloader.
Most of the BCT is interpreted solely by the boot ROM. However, the BCT also includes a "customer data area". This area is ignored by the boot ROM, and its purpose and layout is not defined by hardware. The customer, OEM, or device software author is free to use it for whatever purpose they desire.
The ODMDATA field is very similar to the customer data area; it is also not used or interpreted by the boot ROM. The purpose and layout is also not defined by hardware.
However, NVIDIA-supplied software expects a certain layout and usage for this field. In particular, this field is used to indicate which UART to use for the debug console, as a simple representation of system memory size on older SoCs, and so on.
The ODMDATA layout can vary per board. Some fields, such as those mentioned above, have fixed position and meaning since they are often interpreted by generic software. Other fields are board-specific.
For a complete example for Harmony at one point in time, see http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blob;f=arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h;h=1ec7010911454f19a5018952fd245785a62c59ad;hb=0e52d7fe25b11a656c376a37890be219470661fb.
For details of the fields assumed by upstream software such as U-Boot, see the cbootimage source code.