uboot/arch/arm/mach-stm32mp/cmd_stm32key.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
   2/*
   3 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
   4 */
   5
   6#include <common.h>
   7#include <command.h>
   8#include <console.h>
   9#include <misc.h>
  10#include <dm/device.h>
  11#include <dm/uclass.h>
  12
  13#define STM32_OTP_HASH_KEY_START 24
  14#define STM32_OTP_HASH_KEY_SIZE 8
  15
  16static void read_hash_value(u32 addr)
  17{
  18        int i;
  19
  20        for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) {
  21                printf("OTP value %i: %x\n", STM32_OTP_HASH_KEY_START + i,
  22                       __be32_to_cpu(*(u32 *)addr));
  23                addr += 4;
  24        }
  25}
  26
  27static void fuse_hash_value(u32 addr, bool print)
  28{
  29        struct udevice *dev;
  30        u32 word, val;
  31        int i, ret;
  32
  33        ret = uclass_get_device_by_driver(UCLASS_MISC,
  34                                          DM_GET_DRIVER(stm32mp_bsec),
  35                                          &dev);
  36        if (ret) {
  37                pr_err("Can't find stm32mp_bsec driver\n");
  38                return;
  39        }
  40
  41        for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) {
  42                if (print)
  43                        printf("Fuse OTP %i : %x\n",
  44                               STM32_OTP_HASH_KEY_START + i,
  45                               __be32_to_cpu(*(u32 *)addr));
  46
  47                word = STM32_OTP_HASH_KEY_START + i;
  48                val = __be32_to_cpu(*(u32 *)addr);
  49                misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
  50
  51                addr += 4;
  52        }
  53}
  54
  55static int confirm_prog(void)
  56{
  57        puts("Warning: Programming fuses is an irreversible operation!\n"
  58                        "         This may brick your system.\n"
  59                        "         Use this command only if you are sure of what you are doing!\n"
  60                        "\nReally perform this fuse programming? <y/N>\n");
  61
  62        if (confirm_yesno())
  63                return 1;
  64
  65        puts("Fuse programming aborted\n");
  66        return 0;
  67}
  68
  69static int do_stm32key(cmd_tbl_t *cmdtp, int flag, int argc,
  70                       char * const argv[])
  71{
  72        u32 addr;
  73        const char *op = argc >= 2 ? argv[1] : NULL;
  74        int confirmed = argc > 3 && !strcmp(argv[2], "-y");
  75
  76        argc -= 2 + confirmed;
  77        argv += 2 + confirmed;
  78
  79        if (argc < 1)
  80                return CMD_RET_USAGE;
  81
  82        addr = simple_strtoul(argv[0], NULL, 16);
  83        if (!addr)
  84                return CMD_RET_USAGE;
  85
  86        if (!strcmp(op, "read"))
  87                read_hash_value(addr);
  88
  89        if (!strcmp(op, "fuse")) {
  90                if (!confirmed && !confirm_prog())
  91                        return CMD_RET_FAILURE;
  92                fuse_hash_value(addr, !confirmed);
  93        }
  94
  95        return CMD_RET_SUCCESS;
  96}
  97
  98U_BOOT_CMD(stm32key, 4, 1, do_stm32key,
  99           "Fuse ST Hash key",
 100           "read <addr>: Read the hash store at addr in memory\n"
 101           "stm32key fuse [-y] <addr> : Fuse hash store at addr in otp\n");
 102