Skip to content
Snippets Groups Projects

Simple FRU programmer

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Patrick Huesmann

    Sometimes ipmitool fails to program a fru. It tries to read first and if cannot parse the contents it will silently not do the write operation. That way it is impossible to fix a corrupt FRU. This script uses pyipmi to flash the FRU.

    Edited
    fru-prog.py 3.54 KiB
    #!/usr/bin/env python3
    
    import sys
    import argparse
    import pyipmi.interfaces
    
    
    class IpmiConn():
        def __init__(self, mmc_addr, mch_url, ipmitool_mode=False):
            if ipmitool_mode:
                self.interface = pyipmi.interfaces.create_interface(
                    'ipmitool', interface_type='lan')
            else:
                self.interface = pyipmi.interfaces.create_interface(
                    'rmcp', keep_alive_interval=0)
            self.conn = self.mtca_mch_bridge_amc(mch_url, mmc_addr)
    
        '''
            From https://github.com/kontron/python-ipmi/blob/master/pyipmi/__init__.py#L111
            Example #2: access to an AMC in a uTCA chassis
                slave = 0x81, target = 0x72
                routing = [(0x81,0x20,0),(0x20,0x82,7),(0x20,0x72,None)]
                            uTCA - MCH                        AMC
                        .-------------------.             .--------.
                        |       .-----------|             |        |
                        | ShMC  | CM        |             | MMC    |
             channel=0  |       |           |  channel=7  |        |
         81 ------------| 0x20  |0x82  0x20 |-------------| 0x72   |
                        |       |           |             |        |
                        |       |           |             |        |
                        |       `-----------|             |        |
                        `-------------------´             `--------´
            `------------´     `---´        `---------------´
        '''
    
        def mtca_mch_bridge_amc(self, mch_url: str, amc_mmc_addr: int):
            '''
            Create a "double bridge" IPMI connection to talk directly to a AMC
            '''
            mtca_amc_double_bridge = [(0x81, 0x20, 0),
                                      (0x20, 0x82, 7),
                                      (0x20, amc_mmc_addr, None)]
    
            conn = pyipmi.create_connection(self.interface)
            conn.session.set_session_type_rmcp(mch_url)
            conn.session.set_auth_type_user('', '')
            conn.session.establish()
            conn.target = pyipmi.Target(
                ipmb_address=amc_mmc_addr,
                routing=mtca_amc_double_bridge
            )
            return conn
    
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(
            description='Simple FRU programmer'
        )
        parser.add_argument('mch_addr',
                            type=str,
                            help='IP address or hostname of MCH'
                            )
        parser.add_argument('mmc_addr',
                            type=lambda s: 0x70 + 2*int(s[3:], 0) if s.find("AMC") == 0 else int(s, 0),
                            help='IPMB-L address of MMC or "AMCn" (n=1..12)'
                            )
        parser.add_argument('fru_id',
                            type=int,
                            help='0=AMC, 1=RTM, 2=FMC1, 3=FMC2'
                            )
        parser.add_argument('file_name',
                            type=str,
                            help='Bin file for FRU'
                            )
        parser.add_argument('-d', '--debug',
                            action='store_true',
                            help='pyipmi debug mode'
                            )
        args = parser.parse_args()
    
        ipmi = IpmiConn(args.mmc_addr, args.mch_addr)
    
        with open(args.file_name, "rb") as f:
            fru_data = f.read()
    
        fru_len = len(fru_data)
    
        ipmi.conn.write_fru_data(fru_data, fru_id=args.fru_id)
        fru_data_verify = ipmi.conn.read_fru_data(fru_id=args.fru_id, count=fru_len)
        fru_data_verify = fru_data_verify[:fru_len]
    
        if fru_data != fru_data_verify:
            print('FRU verify error!', file=sys.stderr)
            exit(1)
    
        print('FRU written and verified.\n')
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment