summaryrefslogtreecommitdiffstats
path: root/woferclock/write_vpd
blob: 5774ca17de95a34d2327233824edab1b46376d5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/python
#
# Copyright (c) 2018 Raptor Engineering, LLC
# Released under the terms of the AGPL v3

import sys
import os
import time
import binascii
import subprocess

eeprom_bus = int(sys.argv[1])
if sys.argv[2].startswith("0x") or sys.argv[2].startswith("0X"):
    eeprom_address = int(sys.argv[2][2:], 16)
else:
    eeprom_address = int(sys.argv[2])
filename = sys.argv[3]

with open(filename, 'rb') as f:
    indata = f.read()

raw_data = binascii.hexlify(indata)
vpd_length = len(raw_data)

if vpd_length != 131072:
    print "[ERROR] Invalid VPD length.  Aborting!"
    sys.exit(1)

mod_ret = os.system("modprobe at24")
exit_code = os.WEXITSTATUS(mod_ret)
if exit_code != 0:
    print "[ERROR] at24 driver load failed!"
    sys.exit(1)

with open("/sys/class/i2c-dev/i2c-" + str(eeprom_bus) + "/device/" + str(eeprom_bus) + "-" + format(eeprom_address, '04x') + "/eeprom", 'rb') as f:
    origdata = f.read()

original_data = binascii.hexlify(origdata)

mod_ret = os.system("rmmod at24")
exit_code = os.WEXITSTATUS(mod_ret)
if exit_code != 0:
    print "[ERROR] at24 driver unload failed!"
    sys.exit(1)

address = 0
for i in range(0, vpd_length, 2):
    if original_data[i:(i+2)] != raw_data[i:(i+2)]:
        address_high = hex((address & 65280) >> 8)
        address_low = hex(address & 255)
        command = "i2cset -y " + str(eeprom_bus) + " 0x" + format(eeprom_address, '02x') + " " +  address_high + " " + address_low + " 0x" + raw_data[i:(i+2)] + " i 2>/dev/null"
        try:
            subprocess.check_call(command, stderr=subprocess.STDOUT, shell=True)
        except:
            # Retry, giving the SEEPROM some time to recover
            time.sleep(0.1)
            try:
                subprocess.check_call(command, stderr=subprocess.STDOUT, shell=True)
            except:
                print "[ERROR] Write failed!"
                print "\tCommand was: " + command
                sys.exit(1)
    address = address + 1
    sys.stdout.write(format(address, '05d') + " / " + format((vpd_length / 2), '05d') + "\r")
    sys.stdout.flush()

print ""

mod_ret = os.system("modprobe at24")
exit_code = os.WEXITSTATUS(mod_ret)
if exit_code != 0:
    print "[ERROR] at24 driver load failed!"
    sys.exit(1)

with open("/sys/class/i2c-dev/i2c-" + str(eeprom_bus) + "/device/" + str(eeprom_bus) + "-" + format(eeprom_address, '04x') + "/eeprom", 'rb') as f:
    readdata = f.read()

readback_data = binascii.hexlify(readdata)
if (readback_data != raw_data):
    print "[WARNING] Readback did NOT match provided file!  VPD in unknown state!"
    sys.exit(2)
else:
    print "Done!"
OpenPOWER on IntegriCloud