ippcli Devices and Nodes¶
There are two primary objects for interacting with the devices in the silicon:
For each Device there is exactly one Node, and for each Node, there is exactly one device. Often it may be useful to apply a function to multiple nodes/devices at the same time, and for that you would use a NodeGroup.
Node Groups - Holds multiple nodes for indexing or running a function on
The most common node group used is “ipc.threads”, which exists to be backwards compatible with the DAL/itpii.
Devices¶
The devices primarily hold information about the silicon or portion of silicon it is representing. A list of the known TAP devices can be found via:
>>> ipc.devicelist
Indx DID Alias Type Step Idcode P/D/ C/T Enabled
---------------------------------------------------------------------------------------------------
0 0x00003000 ANN_CLTAPC0 ANN_CLTAPC A0 0x10A84013 0/-/ -/- Yes
1 0x00004000 ANN_SC0 ANN_SC A0 0x0202100B 0/-/ -/- Yes
2 0x00001000 ANN_ARC0 ARC A0 0x200424B1 0/-/ -/0 Yes
3 0x00001001 ANN_AUDIO0 AUDIO A0 0x0B284013 0/-/ -/0 Yes
4 0x00001002 ANN_PSH0 LMT A0 0x18289013 0/-/ -/0 Yes
...
73 0x00005001 SLM_MODULE1 SLM_MODULE E0 0x4A68E013 0/-/ -/- Yes
74 0x00002002 SLM_C2 SLM_C E0 0x4A68E013 0/-/ 0/- Yes
75 0x00001008 SLM_C2_T0 SLM E0 0x4A68E013 0/-/ 0/0 Yes
76 0x00002003 SLM_C3 SLM_C E0 0x4A68E013 0/-/ 1/- Yes
77 0x00001009 SLM_C3_T0 SLM E0 0x4A68E013 0/-/ 1/0 Yes
78 0x00014000 MIPI-PTI InterfacePort 0/-/ -/- Yes
You can also print the device to see some of the known information about that device:
>>> print ipc.devicelist[0]
alias = ANN_CLTAPC0
devicetype = ANN_CLTAPC
stepping = A0 packageid = 0
did = 0x00003000 dieid =
idcode = 0x10a84013 coreid =
irlength = 8 threadid =
isenabled = True instanceid = 0
bustype =
In some cases there may be additional information about the device that is available. To see all that is available on a device, use the built-in python dir command:
>>> print dir(ipc.devicelist[0])
The Device, the Device’s DID, and the Device’s alias are the primary methods of specifying a device when calling in to the IPC CLI functions. However, if the Node is being used (more on that in a bit), then the device does not need to be specified.
You can see from the example above that the Device’s DID does not begin with 0. However, the itpii/DAL started with 0. For backwards compatibility the “Indx” can also be specified when calling in to a function but it is not recommended. It is preferable to use the DID, or even better, the Alias.
The Device List behaves as a list and can be indexed in to (see example above). There are two additional functions that may be useful to many users:
- DeviceList.findByDID(did)¶
Return the device object matching this did.
- Parameters
did – the id of the device to return.
- Returns
The device instance, if found.
- Raises
ValueError – if no matching did is found.
- DeviceList.search(values=None, bywhat=None, **kwargs)¶
Searches through all the known devices and looks for an attribute specified in the ‘bywhat’ variable. Returns a DeviceList with a list of all the devices that matched the search criteria.
- Parameters
values – this can be either a list of values or a regular expression that we will match each devices ‘bywhat’ against.
bywhat – any device attribute to match against.
kwargs – bywhat can be express via kwargs like so: devicetype=value; only one kwarg is currently supported.
ignore_case – (optional) special kwarg that will be looked for (default=True).
- Returns
A devicelist object.
Example
>>> # Search for aliases that match exactly with what is in the specified list >>> ipc.devicelist.search( ["SLM_C0_T0","SLM_C1_T0"] )
>>> # Search for aliases that match the given regular expression >>> ipc.devicelist.search( "SLM_C._T." )
>>> # search for all device types that match the given regular expression >>> ipc.devicelist.search( "SLM", "devicetype" ) >>> ipc.devicelist.search( devicetype = "SLM" )
- Raises
ValueError – if values is None and kwargs is empty
ValueError – if more than 1 kwarg is passed in (not including ignore_case)
ValueError – if no devices with the given attributes were found
- Device.search_children(**kwargs)¶
Search for children and return a list of devices that match the specified criteria.
- Parameters
kwargs – key=value of what to search for. If value is a string, then it is treated like a regular expression.
ignore_case – optional kwarg to specify ignoring case (defaults to True).
- Returns
a devicelist object.
- Raises
ValueError – if kwargs is empty
ValueError – if more than 1 kwarg is passed in (not counting ignore_case)
- Device.search_parents(**kwargs)¶
Search parents and return a list of devices that match the specified criteria.
- Parameters
kwargs – key=value of what to search for. If value is a string, then it is treated like a regular expression.
ignore_case – optional kwarg to specify ignoring case (defaults to True).
- Returns
a devicelist object.
- Raises
ValueError – if kwargs is empty
ValueError – if more than 1 kwarg is passed in (not counting ignore_case)
Nodes¶
Nodes are objects that help map the devices to the functions that those devices support. Currently there is a NodeContainer object that holds all the nodes and it is found here in the ipccli:
>>> ipc.devs.<tab>
ipc.devs.ann_arc0 ipc.devs.ann_iopti0 ipc.devs.ann_pnd0 ipc.devs.ann_usb2phy0
ipc.devs.ann_atpg0 ipc.devs.ann_iosdio0 ipc.devs.ann_pnd_dft0 ipc.devs.ann_usb2pll0
ipc.devs.ann_audio0 ipc.devs.ann_iossp0 ipc.devs.ann_pnd_mbist0 ipc.devs.ann_usb3phy0
ipc.devs.ann_cck0 ipc.devs.ann_iosspa0 ipc.devs.ann_pnd_tap2iosf0 ipc.devs.ann_vsp0
Each Node will have the functions that are supported by that device:
>>> ipc.devs.slm_c0_t0.<tab>
ipc.devs.slm_c0_t0.arch_register()
ipc.devs.slm_c0_t0.asm() ipc.devs.slm_c0_t0.cv ipc.devs.slm_c0_t0.mem()
ipc.devs.slm_c0_t0.asmmode() ipc.devs.slm_c0_t0.device ipc.devs.slm_c0_t0.memblock()
ipc.devs.slm_c0_t0.br() ipc.devs.slm_c0_t0.did ipc.devs.slm_c0_t0.memdump()
ipc.devs.slm_c0_t0.brchange() ipc.devs.slm_c0_t0.dport() ipc.devs.slm_c0_t0.msr()
ipc.devs.slm_c0_t0.breaks ipc.devs.slm_c0_t0.drscan() ipc.devs.slm_c0_t0.name
ipc.devs.slm_c0_t0.brget() ipc.devs.slm_c0_t0.go() ipc.devs.slm_c0_t0.nodetype
ipc.devs.slm_c0_t0.brnew() ipc.devs.slm_c0_t0.halt() ipc.devs.slm_c0_t0.port()
ipc.devs.slm_c0_t0.brremove() ipc.devs.slm_c0_t0.idcode() ipc.devs.slm_c0_t0.state
ipc.devs.slm_c0_t0.cpuid() ipc.devs.slm_c0_t0.invd() ipc.devs.slm_c0_t0.step()
ipc.devs.slm_c0_t0.cpuid_eax() ipc.devs.slm_c0_t0.irdrscan() ipc.devs.slm_c0_t0.thread_status()
ipc.devs.slm_c0_t0.cpuid_ebx() ipc.devs.slm_c0_t0.irdrscanreplace()
NodeContainer¶
The various nodes are attributes off of something called a NodeContainer, but really you most likely just care that it is located here:
>>> ipc.devs
<ipccli.ipc_env.ipc_node_container.NodeContainer object at 0x0000000002C7ECC0>
The node container currently has the following functions for use by users:
- class NodeContainer(base)¶
- group_by(values=None, bywhat=None, **kwargs)¶
Searches through all the known devices and looks for an attribute specified in the ‘bywhat’ variable. Returns a Node Group with a list of all the nodes whose devices matched the search criteria.
- Parameters
values – this can be either a list of values or a regular expression that we will match each devices ‘bywhat’ against.
bywhat – any device attribute to match against.
kwargs – bywhat can be expressed via kwargs like so: devicetype=value.
ignore_case – (optional) special kwarg that will be looked for (default=True).
- Returns
A node group containing all the nodes whose devices matched the search criteria.
See also
Example:
>>> # Search for aliases that match exactly with what is in the specified list >>> threads = ipc.devs.group_by( ["SLM_C0_T0","SLM_C1_T0"] ) >>> # Search for aliases that match the given regular expression >>> threads = ipc.devs.group_by( "SLM_C._T." ) >>> # search for all device types that match the given regular expression >>> threads = ipc.devs.group_by( devicetype="SLM" )
- Raises
ValueError – if values is None and kwargs is empty
ValueError – if no nodes with the given attributes were found
Node Groups¶
A node group is a derivative of a list that will allow you to perform operations across all the nodes in that list. ipc.threads is an example of one such node group and here is an example of reading from all the MSRs on that node group:
>>> ipc.threads.msr(0x400)
GLM_C0_T0.msr - [64b] 0x0000000000000000
GLM_C1_T0.msr - [64b] 0x0000000000000000
GLM_C2_T0.msr - [64b] 0x0000000000000000
GLM_C3_T0.msr - [64b] 0x0000000000000000
The display is showing each node and the value that was received for each node. This is actually a list of values being returned though, so you can index in to that return data if you need to:
>>> data = ipc.threads.msr(0x400)
>>> data[0]
[64b] 0x0000000000000000
>>> data[1]
[64b] 0x0000000000000000
>>> len(data)
0x4
Now, suppose you need to check the value of an MSR across all the threads. The Node group helps shortcut that check by letting you do this:
>>> ipc.threads.msr(0x400) == 0
True
Keep in mind, ALL the nodes must have the same value for that to be true. So if a single thread reports non-zero, then the expression evaluates to False.
StatePort Object¶
The IPC API has a notion of building up multiple operations to build a higher level function called a stateport. The IPC API provides functions for dynamically discovering and creating those functions. Those functions will be under the stateport object under each node.
Device Actions¶
Some nodes support device specific actions. You can find those actions via show actions:
>>> ipc.device_actions.show_actions()
debugport0 - LogInput - ScanEngine procedure that writes the specified input
to the OpenIPC log file (iff ScanEngine logger is
enabled to level Debug) and also returns the input
root - LogInput - ScanEngine procedure that writes the specified input
to the OpenIPC log file (iff ScanEngine logger is
enabled to level Debug) and also returns the input
You can execute those actions off the same device_actions object:
>>> ipc.device_actions.root.LogInput("message for log file")
Or if you have the device-node already, the actions are there as well:
>>> ipc.devs.root.device_actions.LogInput("message for log file")