• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
read_hash_value(u32 addr)16 static 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 
fuse_hash_value(u32 addr,bool print)27 static 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 
confirm_prog(void)55 static 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 
do_stm32key(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])69 static 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 
98 U_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