From dd874f6099177671a7aefb17c8858cc43c3b354e Mon Sep 17 00:00:00 2001 From: Mike Choi Date: Fri, 26 Oct 2018 12:46:31 -0700 Subject: [PATCH] minipack: spi_util.sh improvement (#102) Summary: # Summary: 1. replace "m95m02-util" with "dd" for phy eeprom erase/read/write 2. add debug message for flash erase/read/write 3. add check_parameter() function if the format is not matched will display usage 4. exit program directly in error condition 5. modify usage description # Test plan: ## M95M02 TEST ### Original eeprom image root@bmc-oob: # spi_util.sh read spi2 PIM1 PHY1_EE whole_image_spi_D011_A.bin Select PIM Device: PHY1_EE Config SPI2 Done. 1024+0 records in 1024+0 records out ### Erasing m95m02 test root@bmc-oob: # spi_util.sh erase spi2 PIM1 PHY1_EE Select PIM Device: PHY1_EE Config SPI2 Done. 1024+0 records in 1024+0 records out root@bmc-oob: # spi_util.sh read spi2 PIM1 PHY1_EE erase_content Select PIM Device: PHY1_EE Config SPI2 Done. 1024+0 records in 1024+0 records out root@bmc-oob: # hexdump -C erase_content 00000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| * 00040000 ### Create a small size file to test padding function root@bmc-oob: # echo "fill 0xff test" > fill_test root@bmc-oob: # hexdump -C fill_test 00000000 66 69 6c 6c 20 30 78 66 66 20 74 65 73 74 0a |fill 0xff test.| 0000000f ### Writing m95m02 with a small size image (padding 0xff test) root@bmc-oob: # spi_util.sh write spi2 PIM1 PHY1_EE fill_test Select PIM Device: PHY1_EE Config SPI2 Done. 1024+0 records in 1024+0 records out 1+0 records in 1+0 records out 1024+0 records in 1024+0 records out root@bmc-oob: # spi_util.sh read spi2 PIM1 PHY1_EE read_back_fill_test Select PIM Device: PHY1_EE Config SPI2 Done. 1024+0 records in 1024+0 records out root@bmc-oob: # hexdump -C read_back_fill_test 00000000 66 69 6c 6c 20 30 78 66 66 20 74 65 73 74 0a ff |fill 0xff test..| 00000010 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| * 00040000 root@bmc-oob: # md5sum whole_image_spi_D011_A.bin 8639ab4af04e54da033f17973f2d5779 whole_image_spi_D011_A.bin ### Writing m95m02 with the same size image root@bmc-oob: # spi_util.sh write spi2 PIM1 PHY1_EE whole_image_spi_D011_A.bin Select PIM Device: PHY1_EE Config SPI2 Done. 1024+0 records in 1024+0 records out 1024+0 records in 1024+0 records out root@bmc-oob: # spi_util.sh read spi2 PIM1 PHY1_EE read_back_D011 Select PIM Device: PHY1_EE Config SPI2 Done. 1024+0 records in 1024+0 records out root@bmc-oob: # md5sum read_back_D011 8639ab4af04e54da033f17973f2d5779 read_back_D011 ## DOMFPGA TEST ### Back up original file root@bmc-oob: # spi_util.sh read spi2 PIM1 DOM_FPGA_FLASH dom Select PIM Device: DOM_FPGA_FLASH Config SPI2 Done. delay loop is unreliable, trying to continue flashrom v0.9.8-r1888 on Linux 4.1.51 (armv6l) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... delay loop is unreliable, trying to continue OK. Found Winbond flash chip "W25Q32.V" (4096 kB, SPI) on linux_spi. Reading flash... done. ### Create a small size file to test padding 0xff root@bmc-oob: # echo "a small size file" > test_file root@bmc-oob: # spi_util.sh write spi2 PIM1 DOM_FPGA_FLASH test_file Select PIM Device: DOM_FPGA_FLASH Config SPI2 Done. delay loop is unreliable, trying to continue 1+0 records in 1+0 records out delay loop is unreliable, trying to continue flashrom v0.9.8-r1888 on Linux 4.1.51 (armv6l) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... delay loop is unreliable, trying to continue OK. Found Winbond flash chip "W25Q32.V" (4096 kB, SPI) on linux_spi. Reading old flash chip contents... done. Erasing and writing flash chip... Erase/write done. Verifying flash... VERIFIED. ### Read back and dump root@bmc-oob: # spi_util.sh read spi2 PIM1 DOM_FPGA_FLASH read_back_test Select PIM Device: DOM_FPGA_FLASH Config SPI2 Done. flashrom v0.9.8-r1888 on Linux 4.1.51 (armv6l) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... delay loop is unreliable, trying to continue OK. Found Winbond flash chip "W25Q32.V" (4096 kB, SPI) on linux_spi. Reading flash... done. root@bmc-oob: # hexdump -C read_back_test 00000000 61 20 73 6d 61 6c 6c 20 73 69 7a 65 20 66 69 6c |a small size fil| 00000010 65 0a ff ff ff ff ff ff ff ff ff ff ff ff ff ff |e...............| 00000020 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| * 00400000 ### Read the original file checksum root@bmc-oob: # md5sum dom 92fc035681faf6fbf4c4d49f9bae7ded dom ### Write back the original file (size is equal to flash) root@bmc-oob: # spi_util.sh write spi2 PIM1 DOM_FPGA_FLASH dom Select PIM Device: DOM_FPGA_FLASH Config SPI2 Done. delay loop is unreliable, trying to continue delay loop is unreliable, trying to continue flashrom v0.9.8-r1888 on Linux 4.1.51 (armv6l) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... delay loop is unreliable, trying to continue OK. Found Winbond flash chip "W25Q32.V" (4096 kB, SPI) on linux_spi. Reading old flash chip contents... done. Erasing and writing flash chip... Erase/write done. Verifying flash... VERIFIED. ### Read again and compare the checksum root@bmc-oob: # spi_util.sh read spi2 PIM1 DOM_FPGA_FLASH dom Select PIM Device: DOM_FPGA_FLASH Config SPI2 Done. delay loop is unreliable, trying to continue flashrom v0.9.8-r1888 on Linux 4.1.51 (armv6l) flashrom is free software, get the source code at http://www.flashrom.org Calibrating delay loop... delay loop is unreliable, trying to continue OK. Found Winbond flash chip "W25Q32.V" (4096 kB, SPI) on linux_spi. Reading flash... done. root@bmc-oob: # md5sum dom 92fc035681faf6fbf4c4d49f9bae7ded dom ## Usage display root@bmc-oob: # spi_util.sh Usage: spi_util.sh \ spi1 \ \ spi_util.sh \ spi2 \ \ \ \ : read, write, erase \ : IOB_FPGA_FLASH, TH3_FLASH, BCM5396_EE, BACKUP_BIOS \ : PIM1, PIM2, PIM3, PIM4, PIM5, PIM6, PIM7, PIM8 \ : PHY1_EE, PHY2_EE, PH3_EE, PHY4_EE, DOM_FPGA_FLASH Examples: spi_util.sh write spi1 IOB_FPGA_FLASH iob.bit spi_util.sh read spi2 PIM1 PHY1_EE image.bin spi_util.sh erase spi2 PIM1 DOM_FPGA_FLASH Pull Request resolved: https://github.com/facebookexternal/openbmc.accton/pull/102 Reviewed By: mikechoifb fbshipit-source-id: 30b36d994 --- .../openbmc-utils/files/spi_util.sh | 230 +++++++++++++----- 1 file changed, 175 insertions(+), 55 deletions(-) diff --git a/meta-facebook/meta-minipack/recipes-utils/openbmc-utils/files/spi_util.sh b/meta-facebook/meta-minipack/recipes-utils/openbmc-utils/files/spi_util.sh index 85b0f5425384..cb16b23d2cc3 100644 --- a/meta-facebook/meta-minipack/recipes-utils/openbmc-utils/files/spi_util.sh +++ b/meta-facebook/meta-minipack/recipes-utils/openbmc-utils/files/spi_util.sh @@ -7,24 +7,47 @@ mode_reg=0x3 SMB_CPLD="/sys/class/i2c-adapter/i2c-12/12-003e" SCM_CPLD="/sys/class/i2c-adapter/i2c-2/2-0035" debug=0 +m95m02_page_size=256 +m95m02_page_count=1024 trap cleanup_spi INT TERM QUIT EXIT +function check_flash_info() +{ + spi_no=$1 + flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 +} + function get_flash_first_type() { - type=`flashrom -p linux_spi:dev=/dev/spidev${1}.0 | grep Found \ - | awk 'NR==1' | cut -d '"' -f 2` - echo $type + ori_str=$(check_flash_info ${spi_no}) + type=$(echo ${ori_str} | cut -d '"' -f 2) + if [ $type ];then + echo $type + return 0 + else + echo "Get flash type error: [$ori_str]" + exit -1 + fi } function get_flash_size() { - flash_sz=`flashrom -p linux_spi:dev=/dev/spidev${1}.0 | grep "kB" \ - | awk 'NR==1' | cut -d ' ' -f 6 | cut -d '(' -f 2` - echo $flash_sz + spi_no=$1 + ori_str=$(check_flash_info ${spi_no}) + flash_sz=$(echo ${ori_str} | cut -d '(' -f 3 | cut -d ' ' -f 1) + echo $flash_sz | egrep -q '^[0-9]+$' + num_ret=$? + if [ $num_ret -eq 0 ];then + echo $flash_sz + return 0 + else + echo "Get flash size error: [$ori_str]" + return -1 + fi } -# $1: in file size $2: flash size $3: output file path +# $1: input file size $2: flash size $3: output file path function pad_ff() { out_file=$3 @@ -37,21 +60,32 @@ function resize_file() in_file=$1 out_file=$2 spi_no=$3 + storage_type=$4 in_file_sz=`stat -c%s $in_file` - flash_sz=$(get_flash_size $spi_no) - flash_sz=$(($flash_sz * 1024)) + storage_sz=0 + if [ $storage_type -a $storage_type = "m95m02" ];then + storage_sz=$(($m95m02_page_count * $m95m02_page_size)) + else + flash_sz=$(get_flash_size $spi_no) + if [ $? -eq 0 ];then + storage_sz=$(($flash_sz * 1024)) + else + echo -e "debug message:\n $flash_sz" + exit -1 + fi + fi - if [ $in_file_sz -ne $flash_sz ];then + if [ $in_file_sz -ne $storage_sz ];then cp $in_file $out_file - pad_ff $in_file_sz $flash_sz $out_file + pad_ff $in_file_sz $storage_sz $out_file else - mv $in_file $out_file + ln -s $(realpath ${in_file}) ${out_file} fi } function dump_gpio_config(){ if [ $debug = 0 ]; then - return + return 0 fi echo "Dump SPI configurations..." if [ $1 = "SPI1" ];then @@ -131,6 +165,10 @@ function read_flash_to_file() modprobe spidev type=$(get_flash_first_type $spi_no) flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -r $file -c $type + if [ $? -ne 0 ];then + echo "debug cmd: [flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -r $file -c $type]" + exit -1 + fi } function write_flash_to_file(){ @@ -142,6 +180,10 @@ function write_flash_to_file(){ resize_file $in_file $out_file $spi_no type=$(get_flash_first_type $spi_no) flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -w $out_file -c $type + if [ $? -ne 0 ];then + echo "debug cmd: [flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -w $out_file -c $type]" + exit -1 + fi } function erase_flash(){ @@ -150,6 +192,10 @@ function erase_flash(){ modprobe spidev type=$(get_flash_first_type $spi_no) flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -E -c $type + if [ $? -ne 0 ];then + echo "debug cmd: [flashrom -p linux_spi:dev=/dev/spidev${spi_no}.0 -E -c $type]" + exit -1 + fi } function read_m95m02_to_file(){ @@ -158,18 +204,19 @@ function read_m95m02_to_file(){ eeprom_node="/sys/bus/spi/devices/spi${spi_no}.1/eeprom" modprobe -r at25 modprobe at25 - echo "m95m02 eeprom node: $eeprom_node" - m95m02-util read $eeprom_node $file + dd if=${eeprom_node} of=${file} count=$m95m02_page_count bs=$m95m02_page_size } function write_m95m02(){ spi_no=$1 file=$2 + out_file="/tmp/${3}_spi${1}_tmp" eeprom_node="/sys/bus/spi/devices/spi${spi_no}.1/eeprom" modprobe -r at25 modprobe at25 - echo "m95m02 eeprom node: $eeprom_node" - m95m02-util write $eeprom_node $file + tr '\0' '\377' < /dev/zero | dd count=$m95m02_page_count bs=$m95m02_page_size of=${eeprom_node} + resize_file $file $out_file $spi_no 'm95m02' + dd of=${eeprom_node} if=${out_file} count=$m95m02_page_count bs=$m95m02_page_size } function erase_m95m02(){ @@ -177,8 +224,7 @@ function erase_m95m02(){ eeprom_node="/sys/bus/spi/devices/spi${spi_no}.1/eeprom" modprobe -r at25 modprobe at25 - echo "m95m02 eeprom node: $eeprom_node" - m95m02-util erase $eeprom_node + tr '\0' '\377' < /dev/zero | dd count=$m95m02_page_count bs=$m95m02_page_size of=${eeprom_node} } function read_spi1_dev(){ @@ -275,7 +321,7 @@ function config_spi1_pin_and_path(){ ;; *) echo "Please enter {IOB_FPGA_FLASH, TH3_FLASH, BCM5396_EE, BACKUP_BIOS}" - return + exit -1 ;; esac echo "Config SPI1 Done." @@ -408,16 +454,16 @@ function config_spi2_pim_dev_path(){ ee_sel_ret=$? if [ $spi_sel_ret != 0 ]; then echo "Cannot detect I2C device bus[$bus] addr[$pca9534_spi_sel]" - return - elif [ $ee_sel_ret != 0 ]; then + exit -1 + elif [ $ee_sel_ret != 0 ]; then echo "Cannot detect I2C device bus[$bus] addr[$pca9534_ee_sel]" - return + exit -1 fi i2c_ret=$(i2cget -y $bus $pca9534_spi_sel $mode_reg) if [ $i2c_ret = "" ];then echo "Cannot read bus:$bus addr:$pca9534_spi_sel" - return -1 + exit -1 fi # Current value and with 0xf8 config_val=$(printf "0x%x" $(($spi_sel_output_bit & $i2c_ret))) @@ -426,7 +472,7 @@ function config_spi2_pim_dev_path(){ i2c_ret=$(i2cget -y $bus $pca9534_ee_sel $mode_reg) if [ $i2c_ret = "" ];then echo "Cannot read bus:$bus addr:$pca9534_ee_sel" - return -1 + exit -1 fi config_val=$(printf "0x%x" $(($ee_sel_output_bit & $i2c_ret))) exec_and_print "i2cset -y $bus $pca9534_ee_sel $mode_reg $config_val" @@ -486,12 +532,12 @@ function read_spi2_dev(){ dev=$1 file=$2 - case ${dev:0:4} in - "PHY"[1-4]) + case ${dev} in + "PHY"[1-4]"_EE") # M95M02 EEPROM read_m95m02_to_file $spi_no $file ;; - "DOM_") + "DOM_FPGA_FLASH") # W25Q32 read_flash_to_file $spi_no $file ;; @@ -504,12 +550,12 @@ function read_spi2_dev(){ function write_spi2_dev(){ spi_no=2 dev=$1 - case ${dev:0:4} in - "PHY"[1-4]) + case ${dev} in + "PHY"[1-4]"_EE") # M95M02 EEPROM - write_m95m02 $spi_no $file + write_m95m02 $spi_no $file $dev ;; - "DOM_") # Catch 4 char from "DOM_FPGA_FLASH" + "DOM_FPGA_FLASH") # W25Q32 write_flash_to_file $spi_no $file $dev ;; @@ -522,12 +568,12 @@ function write_spi2_dev(){ function erase_spi2_dev(){ spi_no=2 dev=$1 - case ${dev:0:4} in - "PHY"[1-4]) + case ${dev} in + "PHY"[1-4]"_EE") # M95M02 EEPROM erase_m95m02 $spi_no ;; - "DOM_") # Catch 4 char from "DOM_FPGA_FLASH" + "DOM_FPGA_FLASH") # W25Q32 erase_flash $spi_no ;; @@ -554,7 +600,6 @@ function operate_spi1_dev(){ ;; *) echo "Operation $op is not defined." - usage ;; esac } @@ -576,7 +621,6 @@ function operate_spi2_dev(){ ;; *) echo "Operation $op is not defined." - usage ;; esac } @@ -629,32 +673,108 @@ function ui(){ ;; *) echo "No such SPI bus." - usage return -1 ;; esac - } function usage(){ program=`basename "$0"` - echo "=======================================" echo "Usage:" - echo "$program spi1 " - echo "$program spi2 " - echo " : read, write, erase" - echo " : IOB_FPGA_FLASH, TH3_FLASH, BCM5396_EE, BACKUP_BIOS" - echo " : PIM[1-8]" - echo " : PHY[1-4]_EE, DOM_FPGA_FLASH" - echo "=============== Example ===============" - echo " SPI1 : $program write spi1 IOB_FPGA_FLASH upgrade_file" - echo " SPI2 : $program read spi2 PIM1 PHY1_EE read_eeprom_file" - echo " SPI2 : $program erase spi2 PIM1 DOM_FPGA_FLASH" - echo "=======================================" -} - -if [ $# -ge 1 ] || [ $# -le 5 ]; then - ui $1 $2 $3 $4 $5 + echo "$program spi1 " + echo "$program spi2 " + echo " : read, write, erase" + echo " : IOB_FPGA_FLASH, TH3_FLASH, BCM5396_EE, BACKUP_BIOS" + echo " : PIM1, PIM2, PIM3, PIM4, PIM5, PIM6, PIM7, PIM8" + echo " : PHY1_EE, PHY2_EE, PH3_EE, PHY4_EE, DOM_FPGA_FLASH" + echo "" + echo "Examples:" + echo " $program write spi1 IOB_FPGA_FLASH iob.bit" + echo " $program read spi2 PIM1 PHY1_EE image.bin" + echo " $program erase spi2 PIM1 DOM_FPGA_FLASH" + echo "" +} + +function check_parameter(){ + program=`basename "$0"` + op=$1 + spi=$2 + case ${op} in + "read" | "write" | "erase") + ;; + *) + return -1 + ;; + esac + if [ ${spi} -a ${spi} = "spi1" ]; then + dev=$3 + file=$4 + ## Check device + case ${dev} in + "IOB_FPGA_FLASH" | "TH3_FLASH" | "BCM5396_EE" | "BACKUP_BIOS") + ## Check operation + case ${op} in + "read" | "write") + if [ $# -ne 4 ]; then + return -1 + fi + ;; + "erase") + if [ $# -ne 3 ]; then + return -1 + fi + ;; + esac + ;; + *) + return -1 + ;; + esac + elif [ ${spi} -a ${spi} = "spi2" ]; then + pim=$3 + dev=$4 + file=$5 + ## Check device + case ${pim} in + "PIM"[1-8]) + case ${dev} in + "PHY"[1-4]"_EE" | "DOM_FPGA_FLASH") + ## Check operation + case ${op} in + "read" | "write") + if [ $# -ne 5 ]; then + return -1 + fi + ;; + "erase") + if [ $# -ne 4 ]; then + return -1 + fi + ;; + esac + ;; + *) + return -1 + ;; + esac + ;; + *) + return -1 + ;; + esac + else + return -1 + fi + + return 0 +} + +check_parameter $@ +is_par_ok=$? + +if [ $is_par_ok -eq 0 ]; then + ui $@ else usage + exit -1 fi