# User Interface
This page outlines the low-level mechanisms via which the AMI kernel driver exposes
functionality to userspace code.
Refer to [AMR Management Interface userguide
(ami\_tool)](../deployment/ami-tool-guide.md) for details of how to use
**ami\_tool** (the command line interface tool).
Character Device Files
Each compatible PCI device gets its own character device file under
/dev/ami-bdf-XX:XX.X where the suffix is the PCI Bus:Device.Function (BDF) identifier.
There is one special device file at /dev/ami0 which is a global driver device created
once during driver initialization. Currently, usage of this global device file is not
supported and may be removed in the future.
Example cdev tree with two devices at PCI addresses e2:00.0 and e2:00.1:
/dev/
├── ami0
├── ami-bdf-e2:00.0
├── ami-bdf-e2:00.1
## SYSFS
See https://docs.kernel.org/filesystems/sysfs
Where possible, device attributes are exposed via the sysfs subsystem. This is an
easy-to-use mechanism that maps driver attributes to objects which look and behave
like standard Linux files. These can be opened, read, and (depending on permissions)
written to.
When a user reads or writes to a sysfs node, a callback is triggered in the driver
code. A sysfs tree is created automatically for each PCI device with some standard
attributes. This is located at a path that looks like
/sys/devices/pci0000:XX/0000:XX:YY.Z/0000:XX:YY.Z where the domain (0000), bus (XX),
device (YY), and function (Z) will vary depending on your system setup.
The sysfs tree may also be accessed via:
- /sys/bus/pci/devices/0000:XX:YY.Z - Direct access via PCI device BDF
- /sys/class/hwmon/hwmonX/device - Access via hwmon interface (only available for PF0)
Note: The hwmon interface is only created for Physical Function 0 (PF0). Other
functions (like PF1) will not have hwmon entries but can still be accessed via the PCI
device path.
Driver-Level Attributes
Global driver attributes are located at /sys/bus/pci/drivers/ami/:
- devices - Shows mapping of BDF addresses to device nodes and hwmon IDs
- version - Driver version information
- ami_debug_enabled - Enable/disable debug output (read/write)
Device-Level Attributes
Per-device attributes are located at /sys/bus/pci/devices/0000:XX:YY.Z/:
- logic_uuid - Logic UUID from vendor-specific extended capability
- link_speed_max - Maximum PCIe link speed
- link_speed_current - Current PCIe link speed
- link_width_max - Maximum PCIe link width
- link_width_current - Current PCIe link width
- dev_state - Device state (INIT, READY, MISSING_INFO, NO_AMC, INIT_ERROR, SHUTDOWN,
COMPAT)
- dev_name - Device name (ami-bdf-XX:YY.Z)
- amc_version - AMC firmware version
Example sysfs tree for PF0 with hwmon (standard PCI attributes have been stripped):
/sys/class/hwmon/hwmon3/device
├── logic_uuid
├── link_speed_max
├── link_speed_current
├── link_width_max
├── link_width_current
├── dev_state
├── dev_name
├── amc_version
├── hwmon
│ └── hwmon3
│ ├── curr1_average
│ ├── curr1_input
│ ├── curr1_label
│ ├── curr1_max
│ ├── curr1_status
│ ├── curr2_average
│ ├── curr2_input
│ ├── curr2_label
│ ├── curr2_max
│ ├── curr2_status
│ ├── curr3_average
│ ├── curr3_input
│ ├── curr3_label
│ ├── curr3_max
│ ├── curr3_status
│ ├── device -> ../../../0000:XX:YY.0
│ ├── in0_average
│ ├── in0_input
│ ├── in0_label
│ ├── in0_max
│ ├── in0_status
│ ├── in1_average
│ ├── in1_input
│ ├── in1_label
│ ├── in1_max
│ ├── in1_status
│ ├── in2_average
│ ├── in2_input
│ ├── in2_label
│ ├── in2_max
│ ├── in2_status
│ ├── name
│ ├── power
│ │ ├── async
│ │ ├── autosuspend_delay_ms
│ │ ├── control
│ │ ├── runtime_active_kids
│ │ ├── runtime_active_time
│ │ ├── runtime_enabled
│ │ ├── runtime_status
│ │ ├── runtime_suspended_time
│ │ └── runtime_usage
│ ├── power1_average
│ ├── power1_input
│ ├── power1_label
│ ├── power1_max
│ ├── power1_status
│ ├── subsystem -> ../../../../../../class/hwmon
│ ├── temp1_input
│ ├── temp1_label
│ ├── temp1_max
│ ├── temp1_status
│ ├── temp2_input
│ ├── temp2_label
│ ├── temp2_max
│ ├── temp2_status
│ ├── temp3_input
│ ├── temp3_label
│ ├── temp3_max
│ ├── temp3_status
│ ├── uevent
│ └── update_interval
### Driver Attributes
Driver Attributes
Typically, sysfs is used to expose device attributes; however, the driver itself may
also expose some of its own global attributes. These can be located at
/sys/bus/pci/drivers/ami. Currently, the following attributes are supported:
- devices - When read, returns a map of all PCI devices registered with the driver.
The first line is the total number of devices attached to the driver. Each subsequent
line follows the format " ". This map can be used to
determine where to look for the device you are interested in. For example, the entry
"e2:00.0 1 3" means that the device with BDF e2:00.0 has:
- A character device file at /dev/ami-bdf-e2:00.0 (minor number 1)
- A hwmon tree at /sys/class/hwmon/hwmon3
A hwmon number value of -1 means that the device does not support hwmon functionality
(typically PF1 and higher). All devices will have a valid character device file. Note
that the minor number shown is for informational purposes; the device file name is
based on the BDF address, not the minor number.
- version - When read, returns the current driver version in the format
"MAJOR.MINOR.PATCH +COMMITS *STATUS"
## HWMON
See https://docs.kernel.org/hwmon/hwmon-kernel-api
HWMON builds on the sysfs subsystem to provide sensor monitoring for temperature,
voltage, current, and power sensors. This creates an attribute tree at
/sys/class/hwmon/hwmonX.
Important: HWMON is only available for Physical Function 0 (PF0) and requires:
- A valid AMC (Alveo Management Controller) connection
- The device is not in compatibility mode
- Successful sensor discovery at driver probe time
If these conditions are not met, the device will not have a hwmon interface.
Supported Sensors
The AMI driver exposes the following sensor types via hwmon:
- Temperature sensors (tempX_*) - Up to 20 sensors
- Voltage sensors (inX_*) - Up to 20 sensors
- Current sensors (currX_*) - Up to 20 sensors
- Power sensors (powerX_*) - Up to 5 sensors
Sensor Attributes
For each sensor, the following attributes may be available (depending on what the
hardware supports):
- _input - Current/instantaneous value
- _average - Average value since boot
- _max - Historical maximum value (also used as warning threshold)
- _crit - Critical threshold
- _lcrit - Lower critical threshold
- _max_alarm - Warning threshold alarm status
- _crit_alarm - Critical threshold alarm status
- _lcrit_alarm - Lower critical threshold alarm status
- _label - Human-readable sensor name
- _status - Sensor status information
Not all sensors support all attributes. The available attributes are dynamically
discovered from the AMC firmware via the ASDM (Alveo Sensor Data Model) API at driver
initialization time.
For an example of the HWMON interface structure, see the sysfs section above. For all
intents and purposes, hwmon behaves exactly the same as sysfs - attributes are exposed
as files that can be read (and in some cases written) using standard file I/O
operations.
## IOCTL
IOCTL provides a way to perform arbitrary actions on character device files. An IOCTL
is uniquely defined by a magic number and is executed with the
[ioctl()](https://man7.org/linux/man-pages/man2/ioctl.2) call. Each IOCTL can be
thought of as a unique (and undocumented) system call which can take any arbitrary
argument and copy memory between kernel/user space.
These are used sparingly and only when no other solution exists. The below table
defines the IOCTL calls supported by the AMI driver.
**#define AMI_IOC_MAGIC 'a'**
| IOCTL | Number | Direction | Input Type | Output | Elevated Permissions | Required Device State |
|-------|--------|-----------|------------|--------|----------------------|----------------------|
| AMI_IOC_DOWNLOAD_PDI | 0 | _IOW | struct ami_ioc_data_payload* | N/A | Yes | READY, MISSING_INFO, or COMPAT |
| AMI_IOC_READ_BAR | 1 | _IOWR | struct ami_ioc_bar_data* | Buffer populated | Yes | Any except INIT and SHUTDOWN |
| AMI_IOC_WRITE_BAR | 2 | _IOW | struct ami_ioc_bar_data* | N/A | Yes | Any except INIT and SHUTDOWN |
| AMI_IOC_GET_SENSOR_VALUE | 3 | _IOWR | struct ami_ioc_sensor_value* | Struct populated | No | READY or MISSING_INFO |
| AMI_IOC_DEVICE_BOOT | 4 | _IOW | struct ami_ioc_data_payload* | N/A | Yes | READY, MISSING_INFO, or COMPAT |
| AMI_IOC_COPY_PARTITION | 5 | _IOW | struct ami_ioc_data_payload* | N/A | Yes | READY or MISSING_INFO |
| AMI_IOC_SET_SENSOR_REFRESH | 6 | _IOW | uint16_t | N/A | No | READY or MISSING_INFO |
| AMI_IOC_GET_FPT_HDR | 7 | _IOR | struct ami_ioc_fpt_hdr_value* | Struct populated | No | READY or MISSING_INFO |
| AMI_IOC_GET_FPT_PARTITION | 8 | _IOWR | struct ami_ioc_fpt_partition_value* | Struct populated | No | READY or MISSING_INFO |
| AMI_IOC_SET_FPT_PARTITION | 9 | _IOWR | struct ami_ioc_fpt_partition_value* | Struct updated | Yes | READY or MISSING_INFO |
| AMI_IOC_READ_EEPROM | 10 | _IOWR | struct ami_ioc_eeprom_payload* | EEPROM data | No | READY or MISSING_INFO |
| AMI_IOC_WRITE_EEPROM | 11 | _IOW | struct ami_ioc_eeprom_payload* | N/A | No | READY or MISSING_INFO |
| AMI_IOC_APP_SETUP | 12 | _IOW | enum ami_ioc_app_setup | N/A | No | Any except INIT and SHUTDOWN |
| AMI_IOC_READ_MODULE | 13 | _IOW | struct ami_ioc_module_payload* | Module data | No | READY or MISSING_INFO |
| AMI_IOC_WRITE_MODULE | 14 | _IOW | struct ami_ioc_module_payload* | N/A | No | READY or MISSING_INFO |
| AMI_IOC_DEBUG_VERBOSITY | 15 | _IOW | uint8_t | N/A | No | READY or MISSING_INFO |
### IOCTL Details
#### Input/Output Descriptions
- **AMI_IOC_DOWNLOAD_PDI**: Input struct populated with PDI image data
- **AMI_IOC_READ_BAR**: Input struct with bar/offset/length set; output data copied to
buffer
- **AMI_IOC_WRITE_BAR**: Input struct with bar/offset/length set and buffer populated
with data to write
- **AMI_IOC_GET_SENSOR_VALUE**: Input with hwmon_channel and sensor_type; output
populates val, status, and fresh fields
- **AMI_IOC_DEVICE_BOOT**: Input with partition field set
- **AMI_IOC_COPY_PARTITION**: Input with src and dest fields set
- **AMI_IOC_SET_SENSOR_REFRESH**: Input specifies new sensor refresh timeout
- **AMI_IOC_GET_FPT_HDR**: Output populates FPT header information
- **AMI_IOC_GET_FPT_PARTITION**: Input with partition field set; output populates
remaining fields
- **AMI_IOC_SET_FPT_PARTITION**: Input/output with all fields appropriately set
- **AMI_IOC_READ_EEPROM**: Input with len, addr, and offset; output contains EEPROM
data
- **AMI_IOC_WRITE_EEPROM**: Input with len, addr, offset, and data to write
- **AMI_IOC_APP_SETUP**: Input specifies application setup action
- **AMI_IOC_READ_MODULE**: Input with module parameters; output contains module data
- **AMI_IOC_WRITE_MODULE**: Input with module parameters and data to write
- **AMI_IOC_DEBUG_VERBOSITY**: Input specifies debug level