"Das U-Boot" Source Tree

Add fuse API and commands

This can be useful for fuse-like hardware, OTP SoC options, etc.

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>

authored by

Benoît Thébaudeau and committed by
Stefano Babic
ccca7dfd 6adbd302

+282
+1
README
··· 844 844 CONFIG_CMD_FDOS * Dos diskette Support 845 845 CONFIG_CMD_FLASH flinfo, erase, protect 846 846 CONFIG_CMD_FPGA FPGA device initialization support 847 + CONFIG_CMD_FUSE Device fuse support 847 848 CONFIG_CMD_GETTIME * Get time since boot 848 849 CONFIG_CMD_GO * the 'go' command (exec code) 849 850 CONFIG_CMD_GREPENV * search environment
+1
common/Makefile
··· 111 111 COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o 112 112 endif 113 113 COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o 114 + COBJS-$(CONFIG_CMD_FUSE) += cmd_fuse.o 114 115 COBJS-$(CONFIG_CMD_GETTIME) += cmd_gettime.o 115 116 COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o 116 117 COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
+168
common/cmd_fuse.c
··· 1 + /* 2 + * (C) Copyright 2009-2013 ADVANSEE 3 + * Benoît Thébaudeau <benoit.thebaudeau@advansee.com> 4 + * 5 + * Based on the mpc512x iim code: 6 + * Copyright 2008 Silicon Turnkey Express, Inc. 7 + * Martha Marx <mmarx@silicontkx.com> 8 + * 9 + * See file CREDITS for list of people who contributed to this 10 + * project. 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License as 14 + * published by the Free Software Foundation; either version 2 of 15 + * the License, or (at your option) any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + * 22 + * You should have received a copy of the GNU General Public License 23 + * along with this program; if not, write to the Free Software 24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 25 + * MA 02111-1307 USA 26 + */ 27 + 28 + #include <common.h> 29 + #include <command.h> 30 + #include <fuse.h> 31 + #include <asm/errno.h> 32 + 33 + static int strtou32(const char *str, unsigned int base, u32 *result) 34 + { 35 + char *ep; 36 + 37 + *result = simple_strtoul(str, &ep, base); 38 + if (ep == str || *ep != '\0') 39 + return -EINVAL; 40 + 41 + return 0; 42 + } 43 + 44 + static int confirm_prog(void) 45 + { 46 + puts("Warning: Programming fuses is an irreversible operation!\n" 47 + " This may brick your system.\n" 48 + " Use this command only if you are sure of " 49 + "what you are doing!\n" 50 + "\nReally perform this fuse programming? <y/N>\n"); 51 + 52 + if (getc() == 'y') { 53 + int c; 54 + 55 + putc('y'); 56 + c = getc(); 57 + putc('\n'); 58 + if (c == '\r') 59 + return 1; 60 + } 61 + 62 + puts("Fuse programming aborted\n"); 63 + return 0; 64 + } 65 + 66 + static int do_fuse(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 67 + { 68 + const char *op = argc >= 2 ? argv[1] : NULL; 69 + int confirmed = argc >= 3 && !strcmp(argv[2], "-y"); 70 + u32 bank, word, cnt, val; 71 + int ret, i; 72 + 73 + argc -= 2 + confirmed; 74 + argv += 2 + confirmed; 75 + 76 + if (argc < 2 || strtou32(argv[0], 0, &bank) || 77 + strtou32(argv[1], 0, &word)) 78 + return CMD_RET_USAGE; 79 + 80 + if (!strcmp(op, "read")) { 81 + if (argc == 2) 82 + cnt = 1; 83 + else if (argc != 3 || strtou32(argv[2], 0, &cnt)) 84 + return CMD_RET_USAGE; 85 + 86 + printf("Reading bank %u:\n", bank); 87 + for (i = 0; i < cnt; i++, word++) { 88 + if (!(i % 4)) 89 + printf("\nWord 0x%.8x:", word); 90 + 91 + ret = fuse_read(bank, word, &val); 92 + if (ret) 93 + goto err; 94 + 95 + printf(" %.8x", val); 96 + } 97 + putc('\n'); 98 + } else if (!strcmp(op, "sense")) { 99 + if (argc == 2) 100 + cnt = 1; 101 + else if (argc != 3 || strtou32(argv[2], 0, &cnt)) 102 + return CMD_RET_USAGE; 103 + 104 + printf("Sensing bank %u:\n", bank); 105 + for (i = 0; i < cnt; i++, word++) { 106 + if (!(i % 4)) 107 + printf("\nWord 0x%.8x:", word); 108 + 109 + ret = fuse_sense(bank, word, &val); 110 + if (ret) 111 + goto err; 112 + 113 + printf(" %.8x", val); 114 + } 115 + putc('\n'); 116 + } else if (!strcmp(op, "prog")) { 117 + if (argc < 3) 118 + return CMD_RET_USAGE; 119 + 120 + for (i = 2; i < argc; i++, word++) { 121 + if (strtou32(argv[i], 16, &val)) 122 + return CMD_RET_USAGE; 123 + 124 + printf("Programming bank %u word 0x%.8x to 0x%.8x...\n", 125 + bank, word, val); 126 + if (!confirmed && !confirm_prog()) 127 + return CMD_RET_FAILURE; 128 + ret = fuse_prog(bank, word, val); 129 + if (ret) 130 + goto err; 131 + } 132 + } else if (!strcmp(op, "override")) { 133 + if (argc < 3) 134 + return CMD_RET_USAGE; 135 + 136 + for (i = 2; i < argc; i++, word++) { 137 + if (strtou32(argv[i], 16, &val)) 138 + return CMD_RET_USAGE; 139 + 140 + printf("Overriding bank %u word 0x%.8x with " 141 + "0x%.8x...\n", bank, word, val); 142 + ret = fuse_override(bank, word, val); 143 + if (ret) 144 + goto err; 145 + } 146 + } else { 147 + return CMD_RET_USAGE; 148 + } 149 + 150 + return 0; 151 + 152 + err: 153 + puts("ERROR\n"); 154 + return ret; 155 + } 156 + 157 + U_BOOT_CMD( 158 + fuse, CONFIG_SYS_MAXARGS, 0, do_fuse, 159 + "Fuse sub-system", 160 + "read <bank> <word> [<cnt>] - read 1 or 'cnt' fuse words,\n" 161 + " starting at 'word'\n" 162 + "fuse sense <bank> <word> [<cnt>] - sense 1 or 'cnt' fuse words,\n" 163 + " starting at 'word'\n" 164 + "fuse prog [-y] <bank> <word> <hexval> [<hexval>...] - program 1 or\n" 165 + " several fuse words, starting at 'word' (PERMANENT)\n" 166 + "fuse override <bank> <word> <hexval> [<hexval>...] - override 1 or\n" 167 + " several fuse words, starting at 'word'" 168 + );
+67
doc/README.fuse
··· 1 + Fuse API functions and commands 2 + 3 + The fuse API allows to control a fusebox and how it is used by the upper 4 + hardware layers. 5 + 6 + A fuse corresponds to a single non-volatile memory bit that can be programmed 7 + (i.e. blown, set to 1) only once. The programming operation is irreversible. A 8 + fuse that has not been programmed reads 0. 9 + 10 + Fuses can be used by SoCs to store various permanent configuration and data, 11 + e.g. boot configuration, security configuration, MAC addresses, etc. 12 + 13 + A fuse word is the smallest group of fuses that can be read at once from the 14 + fusebox control IP registers. This is limited to 32 bits with the current API. 15 + 16 + A fuse bank is the smallest group of fuse words having a common ID, as defined 17 + by each SoC. 18 + 19 + Upon startup, the fusebox control IP reads the fuse values and stores them to a 20 + volatile shadow cache. 21 + 22 + See the README files of the drivers implementing this API in order to know the 23 + SoC- and implementation-specific details. 24 + 25 + Functions / commands: 26 + 27 + int fuse_read(u32 bank, u32 word, u32 *val); 28 + fuse read <bank> <word> [<cnt>] 29 + Read fuse words from the shadow cache. 30 + 31 + int fuse_sense(u32 bank, u32 word, u32 *val); 32 + fuse sense <bank> <word> [<cnt>] 33 + Sense - i.e. read directly from the fusebox, skipping the shadow cache - 34 + fuse words. This operation does not update the shadow cache. 35 + 36 + This is useful to know the true value of fuses if an override has been 37 + performed (see below). 38 + 39 + int fuse_prog(u32 bank, u32 word, u32 val); 40 + fuse prog [-y] <bank> <word> <hexval> [<hexval>...] 41 + Program fuse words. This operation directly affects the fusebox and is 42 + irreversible. The shadow cache is updated accordingly or not, depending on 43 + each IP. 44 + 45 + Only the bits to be programmed should be set in the input value (i.e. for 46 + fuse bits that have already been programmed and hence should be left 47 + unchanged by a further programming, it is preferable to clear the 48 + corresponding bits in the input value in order not to perform a new 49 + hardware programming operation on these fuse bits). 50 + 51 + int fuse_override(u32 bank, u32 word, u32 val); 52 + fuse override <bank> <word> <hexval> [<hexval>...] 53 + Override fuse words in the shadow cache. 54 + 55 + The fusebox is unaffected, so following this operation, the shadow cache 56 + may differ from the fusebox values. Read or sense operations can then be 57 + used to get the values from the shadow cache or from the fusebox. 58 + 59 + This is useful to change the behaviors linked to some cached fuse values, 60 + either because this is needed only temporarily, or because some of the 61 + fuses have already been programmed or are locked (if the SoC allows to 62 + override a locked fuse). 63 + 64 + Configuration: 65 + 66 + CONFIG_CMD_FUSE 67 + Define this to enable the fuse commands.
+1
include/config_cmd_all.h
··· 40 40 #define CONFIG_CMD_FDOS /* Floppy DOS support */ 41 41 #define CONFIG_CMD_FLASH /* flinfo, erase, protect */ 42 42 #define CONFIG_CMD_FPGA /* FPGA configuration Support */ 43 + #define CONFIG_CMD_FUSE /* Device fuse support */ 43 44 #define CONFIG_CMD_GETTIME /* Get time since boot */ 44 45 #define CONFIG_CMD_HASH /* calculate hash / digest */ 45 46 #define CONFIG_CMD_HWFLOW /* RTS/CTS hw flow control */
+44
include/fuse.h
··· 1 + /* 2 + * (C) Copyright 2009-2013 ADVANSEE 3 + * Benoît Thébaudeau <benoit.thebaudeau@advansee.com> 4 + * 5 + * Based on the mpc512x iim code: 6 + * Copyright 2008 Silicon Turnkey Express, Inc. 7 + * Martha Marx <mmarx@silicontkx.com> 8 + * 9 + * See file CREDITS for list of people who contributed to this 10 + * project. 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License as 14 + * published by the Free Software Foundation; either version 2 of 15 + * the License, or (at your option) any later version. 16 + * 17 + * This program is distributed in the hope that it will be useful, 18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + * GNU General Public License for more details. 21 + * 22 + * You should have received a copy of the GNU General Public License 23 + * along with this program; if not, write to the Free Software 24 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 25 + * MA 02111-1307 USA 26 + */ 27 + 28 + #ifndef _FUSE_H_ 29 + #define _FUSE_H_ 30 + 31 + /* 32 + * Read/Sense/Program/Override interface: 33 + * bank: Fuse bank 34 + * word: Fuse word within the bank 35 + * val: Value to read/write 36 + * 37 + * Returns: 0 on success, not 0 on failure 38 + */ 39 + int fuse_read(u32 bank, u32 word, u32 *val); 40 + int fuse_sense(u32 bank, u32 word, u32 *val); 41 + int fuse_prog(u32 bank, u32 word, u32 val); 42 + int fuse_override(u32 bank, u32 word, u32 val); 43 + 44 + #endif /* _FUSE_H_ */