From: Sam Protsenko Date: Tue, 18 Nov 2025 23:21:15 +0000 (-0600) Subject: board: samsung: e850-96: Add routines for checking boot dev X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d9aafa751dd76bd3088b746d53004d04fcb9b6c;p=pandora-u-boot.git board: samsung: e850-96: Add routines for checking boot dev Implement functionality to check the current boot device (a device where the SoC ROM code is loading the bootloaders from). The boot device order can be changed using the SW1 DIP switch on the E850-96 board (which controls XOM SoC lines), as stated in [1]. The boot device information is requested from EL3 software using the corresponding SMC call, which in turn reads it from iRAM memory, which was written by the ROM code. New routines decode that data and allow the user to check the current boot device, boot order, etc. That API can be used further to implement different code flows depending on the current boot device, e.g.: - on eMMC boot: obtain the firmware binaries from eMMC - on USB boot: download the firmware over USB instead No functional change; this patch only adds new functionality but it's not used yet. [1] doc/board/samsung/e850-96.rst Signed-off-by: Sam Protsenko Signed-off-by: Minkyu Kang --- diff --git a/board/samsung/e850-96/Makefile b/board/samsung/e850-96/Makefile index 76b8d47994e..e9c62d3181f 100644 --- a/board/samsung/e850-96/Makefile +++ b/board/samsung/e850-96/Makefile @@ -3,4 +3,4 @@ # Copyright (C) 2024, Linaro Limited # Sam Protsenko -obj-y := e850-96.o fw.o acpm.o pmic.o +obj-y := e850-96.o fw.o acpm.o pmic.o bootdev.o diff --git a/board/samsung/e850-96/bootdev.c b/board/samsung/e850-96/bootdev.c new file mode 100644 index 00000000000..7d5ae7128f4 --- /dev/null +++ b/board/samsung/e850-96/bootdev.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2025 Linaro Ltd. + * Author: Sam Protsenko + * + * Routines for checking current boot device. + */ + +#include +#include +#include "bootdev.h" + +/* Flag from BL2 bootloader in RAM */ +#define BL2_TAG_ADDR 0x80000000 /* DRAM base */ +#define BL2_TAG 0xabcdef + +/* Boot device info location in iRAM (only accessible from EL3) */ +#define IRAM_BASE 0x02020000 +#define BOOTDEVICE_INFO_ADDR (IRAM_BASE + 0x64) + +/* SMC call for getting boot device information from EL3 monitor */ +#define SMC_CMD_CHECK_SECOND_BOOT -233 + +/* Boot device constants for the encoded boot device info value */ +#define BD_NO_DEVICE 0x0 +#define BD_UFS 0x1 +#define BD_EMMC 0x2 +#define BD_ERROR 0x3 +#define BD_USB 0x4 +#define BD_SDMMC 0x5 +#define BD_UFS_CARD 0x6 +#define BD_SPI 0x7 + +/* If BL2 bootloader wasn't executed, it means U-Boot is running via JTAG */ +static bool bootdev_is_jtag_session(void) +{ + u32 bl2_tag_val = *(u32 *)BL2_TAG_ADDR; + + return bl2_tag_val != BL2_TAG; +} + +/* Obtain boot device information encoded in 32-bit value */ +static u32 bootdev_get_info(void) +{ + u32 info; + + /* + * On regular boot U-Boot is executed by BL2 bootloader, and is running + * in EL1 mode, so the boot device information has to be obtained via + * SMC call from EL3 software (EL3 monitor), which can read that info + * from the protected iRAM memory. If U-Boot is running via TRACE32 JTAG + * (in EL3 mode), read the boot device info directly from iRAM, as EL3 + * software might not be available. + */ + if (bootdev_is_jtag_session()) { + info = *(u32 *)BOOTDEVICE_INFO_ADDR; + } else { + struct arm_smccc_res res; + + arm_smccc_smc(SMC_CMD_CHECK_SECOND_BOOT, 0, 0, 0, 0, 0, 0, 0, + &res); + info = (u32)res.a2; + } + + return info; +} + +enum bootdev bootdev_get_current(void) +{ + u32 info, magic, order, dev; + + info = bootdev_get_info(); + magic = info >> 24; + order = info & 0xf; + dev = (info >> (4 * order)) & 0xf; + + if (magic != 0xcb) + panic("Abnormal boot"); + + switch (dev) { + case BD_UFS: + return BOOTDEV_UFS; + case BD_EMMC: + return BOOTDEV_EMMC; + case BD_USB: + return BOOTDEV_USB; + case BD_SDMMC: + return BOOTDEV_SD; + default: + return BOOTDEV_ERROR; + } + + return BOOTDEV_ERROR; +} + +bool bootdev_is_usb(void) +{ + return bootdev_get_current() == BOOTDEV_USB; +} diff --git a/board/samsung/e850-96/bootdev.h b/board/samsung/e850-96/bootdev.h new file mode 100644 index 00000000000..5f454bf0090 --- /dev/null +++ b/board/samsung/e850-96/bootdev.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2025 Linaro Ltd. + * Sam Protsenko + */ + +#ifndef __E850_96_BOOTDEV_H +#define __E850_96_BOOTDEV_H + +#include + +enum bootdev { + BOOTDEV_ERROR, + BOOTDEV_SD, + BOOTDEV_EMMC, + BOOTDEV_USB, + BOOTDEV_UFS, +}; + +enum bootdev bootdev_get_current(void); +bool bootdev_is_usb(void); + +#endif /* __E850_96_BOOTDEV_H */