# 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