The Platform Communication Channel Table contains information used to send messages in a shared memory buffer between the Operating System and other subsystems on the platform. Typically, the Channel has an interrupt defined that is used to tell the other subsystem that there is new data available.
Recently, I’ve been working with a couple entries that are of a newer type. In addition to the shared memory region and the interrupt values, the PCCT entries for type 3 and type 4 channels also have a series of registers. Where before the PCCT entries were normalized, now they are hierarchical. This makes them a little harder to scan with the human eye to confirm that the proper values have been recorded and read.
To simplify development, I build a simple script.
#!/usr/bin/python3 import json import pdb pcct = dict() def to_json(): current = pcct parent = pcct with open("pcct.dsl", "r") as f: for line in f: if line.startswith("["): index = line.find("]") data = line[index +1:] index = data.find(":") key = data[0:index].strip() value = data[index+1:].strip() if (key == 'Subtable Type'): #subcount = 1 parent = dict() subtables = pcct.get('subtables',) subtables.append(parent) current = parent pcct['subtables'] = subtables elif value == "[Generic Address Structure]": current = dict() parent[key] = current current[key] = value def report_on_pcct(): for sub in pcct['subtables']: sub_type = sub['Subtable Type'] if sub_type.startswith('03') or sub_type.startswith('04'): print(sub_type) print( " %29s = %s" % ( "Base Address", sub.get('Base Address',"unset"))) print( " %29s = %s" % ( "Platform Interrupt ", sub.get('Platform Interrupt',"unset"))) for key, value in sub.items(): if isinstance(value, dict): if value.get(key, '') == "[Generic Address Structure]": print( " %29s Address = %s" % ( key, value.get('Address',"unset"))) for k2, v2 in value.items(): if k2.endswith('Mask'): print( " %29s = %s" % ( k2, v2)) to_json() print(json.dumps(pcct, indent =2)) report_on_pcct()
Even in a simple script like this, I tend to iterate. My origianl intention was to merely convert the PCCT to JSON and then use jq to query it. Halfway through I realized it was easier to do the query in python. So, while I am still outputing the whole table in JSON, I display the values I actually care about underneath it.
Here is some of the output from a sample run:
03 [Extended PCC Master Subspace] Base Address = 00004000000D4004 Platform Interrupt = 0000002E Doorbell Register Address = 00004000006B6010 Preserve Mask = 0000000000000000 Write Mask = 0000000000000000 Platform ACK Register Address = 00004000006B6020 ACK Preserve Mask = 0000000000000000 ACK Set Mask = 0000000000000001 Command Complete Register Address = 00004000000D4000 Command Complete Check Mask = 0000000000000001 Command Update Register Address = 00004000000D4000 Command Update Preserve Mask = 0000000000FF0004 Command Update Set Mask = 0000000000000000 Error Status Register Address = 00004000000D4000 Error Status Mask = 0000000000000004
I made an effort at lining up the output values. Aside from neatness, it makes it easier to scan down the column.
Writing this allowed us to zoom in on the fact that the preserve and write masks were both 0. This was quickly confirmed to be correct. This is not the final set of values for this table, just an interim copy that we checked.
This script is a good example of Data munging. The idea is that it is a four stage process: read, convert to a standard form, query. The standard internal form means you can mix and match on the reading and the query portions with other code should you with to do so.