#!/usr/bin/env python3 import os import sys import mmap import time import fcntl import struct import array import subprocess import json import requests import re from os.path import expanduser from ogcli.raml_api import overrides TOKENFILE = expanduser("~/.token") # Create api token def createToken(): # minimal, fast-loading requests alternative import ogcli.requests_lite as requests # use current cli session to fetch an api token cli_session_binary = getattr(overrides, "CLI_SESSION_BINARY", "/usr/libexec/cli-session") token = subprocess.run([cli_session_binary], stdout=subprocess.PIPE).stdout.decode('utf-8') # write token to file with open(TOKENFILE, "w") as f: f.write(token) # store token in var header headers = { 'Authorization' : 'Token ' + token } return headers # Get system model and firmware version def getInfo(): # call createToken() to get api token headers = createToken() # Set up api gets serial = requests.get('https://localhost/api/v2/system/serial_number', headers=headers, verify=False) model = requests.get('https://localhost/api/v2/system/model_name', headers=headers, verify=False) # Get data & convert json into dictionaries s = json.loads(serial.text)['system_serial_number']['serial_number'] m = json.loads(model.text)['system_model_name']['model_name'] # Print output print(f'\nSerial: {s}') print(f'Model: {m}\n\n') getInfo() # Memory info I2C_SMBUS_READ = 1 I2C_SMBUS_BYTE_DATA = 2 def smbus_read_byte_data(fd, command): smbus = array.array("B", struct.pack("BH32s", 0, 0, bytearray(32))) s = struct.pack("BBIP", I2C_SMBUS_READ, command, I2C_SMBUS_BYTE_DATA, smbus.buffer_info()[0]) fcntl.ioctl(fd, 0x0720, s, True) data = struct.unpack("BBIP", s) byte, word, block = struct.unpack("BH32s", smbus) return byte & 0xff I2C_FUNC_SMBUS_READ_BYTE_DATA = 0x00080000 def i2c_funcs(fd): # funcs support buf = array.array("I", [0]) fcntl.ioctl(fd, 0x0705, buf, True) return buf[0] def i2c_address(fd, address): fcntl.ioctl(fd, 0x0703, address, True) def dump_spd(address): fd = os.open("/dev/i2c-0", os.O_RDWR) if i2c_funcs(fd) & I2C_FUNC_SMBUS_READ_BYTE_DATA == 0: raise Exception("Missing smbus i2c support") i2c_address(fd, address) for i in range(0, 256, 16): dataline = "" characters = "" for j in range(0, 16): data = smbus_read_byte_data(fd, i + j) dataline += " {:02x}".format(data) characters += chr(data) if data >= ord(" ") and data <= ord("~") else "." #print("{:02x}:{} {}".format(i, dataline, characters)) # write dump to a temp file with open ("temp.txt", "a+") as f: f.write("{:02x}:{} {}\n".format(i, dataline, characters)) f.close() # parse file and print if "80:" is found in the file with open("temp.txt", "r") as g: for line in g: if "80:" in line: print(line) g.close # delete temp.txt os.system('rm temp.txt') os.close(fd) # dimm-0 0x50 # dimm-1 0x51 for index in range(2): #print("Dump SPD for SO-DIMM {}".format(index)) try: dump_spd(0x50 + index) print() except: print() #print(" - No Dimm?") # print() # print("Dump Memory Controller Configuration") # # memory controller @ D 18h Fn 2 - configuration space registers # mem_pci_fd = os.open("/sys/devices/pci0000:00/0000:00:18.2/config", os.O_RDONLY | os.O_SYNC) # def pread32(reg): # os.lseek(mem_pci_fd, reg, os.SEEK_SET) # data = os.read(mem_pci_fd, 4) # if len(data) != 4: # raise Exception("Failed read") # return struct.unpack("=I", data)[0] # dram_timing_high = 0x8c # dram_t_low = pread32(0x88) # dram_t_high = pread32(0x8c) # dram_cfg_low = pread32(0x90) # dram_cfg_high = pread32(0x94) # dram_timing0 = pread32(0x200) # dram_timing1 = pread32(0x204) # dram_timing2 = pread32(0x208) # dram_timing3 = pread32(0x20c) # dram_speeds = { # 0x02: (200, "400MT/s"), # 0x04: (333, "667MT/s"), # 0x06: (400, "800MT/s"), # 0x0a: (533, "1066MT/s"), # 0x0e: (667, "1333MT/s"), # 0x12: (800, "1600MT/s"), # 0x16: (933, "1866MT/s"), # 0x1a: (1066, "2133MT/s"), # } # if dram_cfg_high & 0x80 != 0: # dram_mem_clk_freq = (dram_cfg_high & 0x1f) # dram_mem_clk_freq_v = dram_speeds.get(dram_mem_clk_freq, (None, "Unknown")) # dram_mem_clk_freq_val = dram_mem_clk_freq_v[0] # print("dram memclkfreq = {} MHz {} (0x{:x})".format( # dram_mem_clk_freq_v[0], dram_mem_clk_freq_v[1], # dram_mem_clk_freq)) # else: # print("dram memclkfreq not valid") # unbuff_dimm = (dram_cfg_low & (1 << 16) != 0) # print(f"unbuffered dimm = {unbuff_dimm}") # # "disable" bits # memclocks = (dram_t_low >> 24) & 0x3f # for i in range(6): # print(f"memclock[{i}] = {(memclocks & (1 << i)) == 0}") # timing_2t = (dram_cfg_high & (1 << 20) != 0) # print(f"timing 2T {timing_2t}") # print(f"autorefresh = {(dram_t_high & (1 << 18)) == 0}") # tref = (dram_t_high >> 16) & 0x3 # print("tref = {}".format({ # 0: "Undefined", # 1: "Reserved", # 2: "7.8us", # 3: "3.9us", # }.get(tref))) # def clk_to_ns(c): # return c * (1000 / dram_mem_clk_freq_val) # tras = (dram_timing0 >> 24) & 0x3f # trp = (dram_timing0 >> 16) & 0x1f # trcd = (dram_timing0 >> 8) & 0x1f # tcl = (dram_timing0 >> 0) & 0x1f # trtp = (dram_timing1 >> 24) & 0xf # tfaw = (dram_timing1 >> 16) & 0x3f # trrd = (dram_timing1 >> 8) & 0xf # trc = (dram_timing1 >> 0) & 0x3f # trfc3 = (dram_timing2 >> 24) & 0x7 # trfc2 = (dram_timing2 >> 16) & 0x7 # trfc1 = (dram_timing2 >> 8) & 0x7 # trfc0 = (dram_timing2 >> 0) & 0x7 # twtr = (dram_timing3 >> 8) & 0xf # tcwl = (dram_timing3 >> 0) & 0x1f # for k in ["tRAS", "tRP", "tRCD", "tCL", "tRTP", "tFAW", "tRRD", "tRC"]: # v = locals().get(k.casefold()) # print("{} = {} clocks ({:.4f} ns)".format(k, v, clk_to_ns(v))) # print(f"SPD timing format (tCL-tRCD-tRP-tRAS) = {tcl}-{trcd}-{trp}-{tras}") # for k in ["tRFC0", "tRFC1", "tRFC2", "tRFC3"]: # v = locals().get(k.casefold()) # print("{} = 0x{:x}".format(k, v))