| 214 | * via Linux: |
| 215 | {{{#!bash |
| 216 | # read OTP fuse |
| 217 | # $1 bank |
| 218 | # $2 word |
| 219 | # OTP is arranged as banks of 32bit words so we access with bs=4 and skip to the word we want |
| 220 | OCOTP_DEV=/sys/devices/platform/soc@0/30000000.bus/30350000.efuse/imx-ocotp0/nvmem |
| 221 | fuse_read() |
| 222 | { |
| 223 | local bank=$1 |
| 224 | local word=$2 |
| 225 | local offset=$(($((bank*4))+((word%4)))) |
| 226 | # and can use hexdump to display as a 32bit int |
| 227 | dd if=$OCOTP_DEV bs=4 count=1 skip=$offset 2>/dev/null | hexdump -v -e '1/4 "0x%08x"' |
| 228 | } |
| 229 | |
| 230 | # blow OTP fuse |
| 231 | # $1 bank |
| 232 | # $2 word |
| 233 | # $3 value |
| 234 | fuse_blow() { |
| 235 | local bank=$1 |
| 236 | local word=$2 |
| 237 | local val=$3 |
| 238 | local offset=$(($((bank*4))+((word%4)))) |
| 239 | |
| 240 | echo "fuse_blow: bank$bank word$word offset=$offset val=$val" |
| 241 | # output binary 32bit int |
| 242 | local b0=$(( $((val>>24)) & 0xff)) |
| 243 | local b1=$(( $((val>>16)) & 0xff)) |
| 244 | local b2=$(( $((val>>8)) & 0xff)) |
| 245 | local b3=$(( $((val>>0)) & 0xff)) |
| 246 | printf "\\x$(printf "%x" $b3)\\x$(printf "%x" $b2)\\x$(printf "%x" $b1)\\x$(printf "%x" $b0)" | |
| 247 | dd of=$OCOTP_DEV bs=4 seek=$offset 2>/dev/null |
| 248 | } |
| 249 | |
| 250 | echo "Current SRK_FUSES:" |
| 251 | echo $(fuse_read 6 0) |
| 252 | echo $(fuse_read 6 1) |
| 253 | echo $(fuse_read 6 2) |
| 254 | echo $(fuse_read 6 3) |
| 255 | echo $(fuse_read 7 0) |
| 256 | echo $(fuse_read 7 1) |
| 257 | echo $(fuse_read 7 2) |
| 258 | echo $(fuse_read 7 3) |
| 259 | echo $(fuse_read 1 3) |
| 260 | |
| 261 | echo "Blowing fuses from $SRK_HASH..." |
| 262 | bank=6 |
| 263 | word=0 |
| 264 | for i in $(hexdump -e '/4 "0x"' -e '/4 "%X""\n"' $SRK_HASH); do |
| 265 | fuse_blow $bank $word $i |
| 266 | word=$((word+1)) |
| 267 | [ $word -eq 4 ] && { |
| 268 | word=0 |
| 269 | bank=$((bank+1)) |
| 270 | } |
| 271 | done |
| 272 | }}} |