rpi: Capture the device tree passed from the bootloader.

The Raspberry Pi bootloader (bootcode.bin and start.elf) will load
the device tree from the same FAT partition and combine it with
device tree overlays specified in config.txt. This device tree is then
passed to the kernel (in this case U-Boot) in the r2 register.

This patch retrieves the machine id (r1 register) and the device tree
(r2 register) passed to U-Boot and store those in environment variables
on boot so boot scripts can refer to those and pass them to the kernel.

When CONFIG_OF_BOARD is defined, the same device tree passed to U-Boot
will be used in lieu of bundling one with the U-Boot image at build
time.

Bug: 31636643
Test: Booted a Raspberry Pi3 passing the DT from the bootloader.
Change-Id: Ibf9c754719b3e0f41d20382833abf853ba7613e2
This commit is contained in:
Alex Deymo 2016-09-23 10:28:10 -07:00 committed by Kever Yang
parent 8f9ff70555
commit dd3908179b
1 changed files with 61 additions and 0 deletions

View File

@ -348,11 +348,72 @@ static void set_serial_number(void)
env_set("serial#", serial_string);
}
/* Save parameters passed from the bootloader. Initialize these in a non-zero
* value to force them to be placed in .data instead of .bss since the .bss
* section will be initialized with 0 later in the boot process. */
static u32 _saved_boot_r0 = 1;
static u32 _saved_boot_r1 = 2;
static u32 _saved_boot_r2 = 3;
void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) {
_saved_boot_r0 = r0;
_saved_boot_r1 = r1;
_saved_boot_r2 = r2;
save_boot_params_ret();
}
/* Returns whether we got passed a FDT from the bootloader. If it was passed,
* it returns the address of it. Otherwise returns NULL.
*
* The RPi start.elf passes important system configuration like memory sizes
* and overlays attached as configured in the config.txt file via a Device Tree.
*
* start.elf determines whether the kernel (in this case U-Boot) supports DT by
* looking at a the tail of the kernel file which is added by mkknlimg tool in
* the following repository:
*
* https://github.com/raspberrypi/tools/blob/master/mkimage/knlinfo
*
* To force start.elf to pass a combined, ready-to-go DT, you have to use the
* mkknlimg tool on the kernel the raspberry bootloader is using, that is, the
* u-boot.bin image:
*
* ./mkknlimg --dtok u-boot.bin /boot/u-boot.bin
*/
static void* rpi_passed_fdt(void)
{
if (_saved_boot_r0 != 0 || fdt_check_header((void *)_saved_boot_r2))
return NULL;
return (void *)_saved_boot_r2;
}
void* board_fdt_blob_setup(void)
{
return rpi_passed_fdt();
}
static void set_boot_args(void)
{
struct fdt_header *passed_fdt = rpi_passed_fdt();
if (passed_fdt == NULL)
return;
/* Set the machine id from r1 register and FDT from register r2. */
setenv_hex("machid", _saved_boot_r1);
setenv_hex("fdt_addr_r", _saved_boot_r2);
/* Setting fdt_high forces the updated FDT generated by U-Boot to be
* placed at this address. We choose to place it 512 KiB before the
* passed FDT, limiting the FDT size to 512 KiB. */
setenv_hex("fdt_high", _saved_boot_r2 - 512 * 1024);
}
int misc_init_r(void)
{
set_fdt_addr();
set_fdtfile();
set_usbethaddr();
set_boot_args();
#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
set_board_info();
#endif