Skip to content

Commit

Permalink
firmware: raspberrypi: Add support for tryonce reboot flag
Browse files Browse the repository at this point in the history
Define a new mailbox (SET_REBOOT_FLAGS) which may be used to
pass optional flags to the Raspberry Pi firmware that changes
the behaviour of the bootloader and firmware during a reboot.

Currently this just defines the 'tryboot' flag which causes
the firmware to load tryboot.txt instead config.txt. This
alternate configuration file can be used to specify the
path of an alternate firmware and kernels allowing a fallback
mechanism to be implemented for OS upgrades.
  • Loading branch information
timg236 authored and popcornmix committed Nov 17, 2020
1 parent 36b99de commit 0f8dd79
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
25 changes: 23 additions & 2 deletions drivers/firmware/raspberrypi.c
Expand Up @@ -195,6 +195,7 @@ static int rpi_firmware_notify_reboot(struct notifier_block *nb,
{
struct rpi_firmware *fw;
struct platform_device *pdev = g_pdev;
u32 reboot_flags = 0;

if (!pdev)
return 0;
Expand All @@ -203,8 +204,28 @@ static int rpi_firmware_notify_reboot(struct notifier_block *nb,
if (!fw)
return 0;

(void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT,
0, 0);
// The partition id is the first parameter followed by zero or
// more flags separated by spaces indicating the reason for the reboot.
//
// 'tryboot': Sets a one-shot flag which is cleared upon reboot and
// causes the tryboot.txt to be loaded instead of config.txt
// by the bootloader and the start.elf firmware.
//
// This is intended to allow automatic fallback to a known
// good image if an OS/FW upgrade fails.
//
// N.B. The firmware mechanism for storing reboot flags may vary
// on different Raspberry Pi models.
if (data && strstr(data, " tryboot"))
reboot_flags |= 0x1;

// The mailbox might have been called earlier, directly via vcmailbox
// so only overwrite if reboot flags are passed to the reboot command.
if (reboot_flags)
(void)rpi_firmware_property(fw, RPI_FIRMWARE_SET_REBOOT_FLAGS,
&reboot_flags, sizeof(reboot_flags));

(void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, NULL, 0);

return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions include/soc/bcm2835/raspberrypi-firmware.h
Expand Up @@ -97,6 +97,8 @@ enum rpi_firmware_property_tag {
RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049,
RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050,
RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058,
RPI_FIRMWARE_GET_REBOOT_FLAGS = 0x00030064,
RPI_FIRMWARE_SET_REBOOT_FLAGS = 0x00038064,

/* Dispmanx TAGS */
RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,
Expand Down

0 comments on commit 0f8dd79

Please sign in to comment.