diff options
Diffstat (limited to 'util')
-rwxr-xr-x | util/cbmem/cbmem.py | 259 |
1 files changed, 0 insertions, 259 deletions
diff --git a/util/cbmem/cbmem.py b/util/cbmem/cbmem.py deleted file mode 100755 index 70ccc00afc..0000000000 --- a/util/cbmem/cbmem.py +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/python -# -# cbmem.py - Linux space CBMEM contents parser -# -# Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -''' -Parse and display CBMEM contents. - -This module is meant to run on systems with coreboot based firmware. - -When started, it determines the amount of DRAM installed on the system, and -then scans the top area of DRAM (right above the available memory size) -looking for the CBMEM base signature at locations aligned at 0x20000 -boundaries. - -Once it finds the CBMEM signature, the utility parses the contents, reporting -the section IDs/sizes and also reporting the contents of the tiemstamp and -console sections. -''' - -import mmap -import struct -import sys - -def get_phys_mem(addr, size): - '''Read size bytes from address addr by mmaping /dev/mem''' - - mf = open("/dev/mem") - delta = addr % 4096 - mm = mmap.mmap(mf.fileno(), size + delta, - mmap.MAP_PRIVATE, offset=(addr - delta)) - buf = mm.read(size + delta) - mf.close() - return buf[delta:] - -# This class and metaclass make it easier to define and access structures -# which live in physical memory. To use them, inherit from CStruct and define -# a class member called struct_members which is a tuple of pairs. The first -# item in the pair is the type format specifier that should be used with -# struct.unpack to read that member from memory. The second item is the name -# that member should have in the resulting object. - -class MetaCStruct(type): - def __init__(cls, name, bases, dct): - struct_members = dct["struct_members"] - cls.struct_fmt = "<" - for char, name in struct_members: - cls.struct_fmt += char - cls.struct_len = struct.calcsize(cls.struct_fmt) - super(MetaCStruct, cls).__init__(name, bases, dct) - -class CStruct(object): - __metaclass__ = MetaCStruct - struct_members = () - - def __init__(self, addr): - self.raw_memory = get_phys_mem(addr, self.struct_len) - values = struct.unpack(self.struct_fmt, self.raw_memory) - names = (name for char, name in self.struct_members) - for name, value in zip(names, values): - setattr(self, name, value) - -def normalize_timer(value, freq): - '''Convert timer reading into microseconds. - - Get the free running clock counter value, divide it by the clock frequency - and multiply by 1 million to get reading in microseconds. - - Then convert the value into an ASCII string with groups of three digits - separated by commas. - - Inputs: - value: int, the clock reading - freq: float, the clock frequency - - Returns: - A string presenting 'value' in microseconds. - ''' - - result = [] - value = int(value * 1000000.0 / freq) - svalue = '%d' % value - vlength = len(svalue) - remainder = vlength % 3 - if remainder: - result.append(svalue[0:remainder]) - while remainder < vlength: - result.append(svalue[remainder:remainder+3]) - remainder = remainder + 3 - return ','.join(result) - -def get_cpu_freq(): - '''Retrieve CPU frequency from sysfs. - - Use /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq as the source. - ''' - freq_str = open('/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq' - ).read() - # Convert reading into Hertz - return float(freq_str) * 1000.0 - -def process_timers(base): - '''Scan the array of timestamps found in CBMEM at address base. - - For each timestamp print the timer ID and the value in microseconds. - ''' - - class TimestampHeader(CStruct): - struct_members = ( - ("Q", "base_time"), - ("L", "max_entr"), - ("L", "entr") - ) - - class TimestampEntry(CStruct): - struct_members = ( - ("L", "timer_id"), - ("Q", "timer_value") - ) - - header = TimestampHeader(base) - print('\ntime base %d, total entries %d' % (header.base_time, header.entr)) - clock_freq = get_cpu_freq() - base = base + header.struct_len - prev_time = 0 - for i in range(header.entr): - timestamp = TimestampEntry(base) - print '%d:%s ' % (timestamp.timer_id, - normalize_timer(timestamp.timer_value, clock_freq)), - if prev_time: - print '(%s)' % normalize_timer( - timestamp.timer_value - prev_time, clock_freq), - prev_time = timestamp.timer_value - print - base = base + timestamp.struct_len - print - -def process_console(base): - '''Dump the console log buffer contents found at address base.''' - - class ConsoleHeader(CStruct): - struct_members = ( - ("L", "size"), - ("L", "cursor") - ) - - header = ConsoleHeader(base) - print 'cursor at %d\n' % header.cursor - - cons_addr = base + header.struct_len - cons_length = min(header.cursor, header.size) - cons_text = get_phys_mem(cons_addr, cons_length) - print cons_text - print '\n' - -def ipchksum(buf): - '''Checksumming function used on the coreboot tables. The buffer being - checksummed is summed up as if it was an array of 16 bit unsigned - integers. If there are an odd number of bytes, the last element is zero - extended.''' - - size = len(buf) - odd = size % 2 - fmt = "<%dH" % ((size - odd) / 2) - if odd: - fmt += "B" - shorts = struct.unpack(fmt, buf) - checksum = sum(shorts) - checksum = (checksum >> 16) + (checksum & 0xffff) - checksum += (checksum >> 16) - checksum = ~checksum & 0xffff - return checksum - -def parse_tables(base, length): - '''Find the coreboot tables in memory and process whatever we can.''' - - class CBTableHeader(CStruct): - struct_members = ( - ("4s", "signature"), - ("I", "header_bytes"), - ("I", "header_checksum"), - ("I", "table_bytes"), - ("I", "table_checksum"), - ("I", "table_entries") - ) - - class CBTableEntry(CStruct): - struct_members = ( - ("I", "tag"), - ("I", "size") - ) - - class CBTableForward(CBTableEntry): - struct_members = CBTableEntry.struct_members + ( - ("Q", "forward"), - ) - - class CBMemTab(CBTableEntry): - struct_members = CBTableEntry.struct_members + ( - ("L", "cbmem_tab"), - ) - - for addr in range(base, base + length, 16): - header = CBTableHeader(addr) - if header.signature == "LBIO": - break - else: - return -1 - - if header.header_bytes == 0: - return -1 - - if ipchksum(header.raw_memory) != 0: - print "Bad header checksum" - return -1 - - addr += header.header_bytes - table = get_phys_mem(addr, header.table_bytes) - if ipchksum(table) != header.table_checksum: - print "Bad table checksum" - return -1 - - for i in range(header.table_entries): - entry = CBTableEntry(addr) - if entry.tag == 0x11: # Forwarding entry - return parse_tables(CBTableForward(addr).forward, length) - elif entry.tag == 0x16: # Timestamps - process_timers(CBMemTab(addr).cbmem_tab) - elif entry.tag == 0x17: # CBMEM console - process_console(CBMemTab(addr).cbmem_tab) - - addr += entry.size - - return 0 - -def main(): - for base, length in (0x00000000, 0x1000), (0x000f0000, 0x1000): - if parse_tables(base, length): - break - else: - print "Didn't find the coreboot tables" - return 0 - -if __name__ == "__main__": - sys.exit(main()) |