diff options
| -rw-r--r-- | board/samsung/e850-96/Makefile | 2 | ||||
| -rw-r--r-- | board/samsung/e850-96/bootdev.c | 99 | ||||
| -rw-r--r-- | board/samsung/e850-96/bootdev.h | 23 |
3 files changed, 123 insertions, 1 deletions
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 <[email protected]> -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 <[email protected]> + * + * Routines for checking current boot device. + */ + +#include <linux/arm-smccc.h> +#include <vsprintf.h> +#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 <[email protected]> + */ + +#ifndef __E850_96_BOOTDEV_H +#define __E850_96_BOOTDEV_H + +#include <stdbool.h> + +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 */ |
