From f46bd2a058db7acbc9012a657f3fbe79d49c017f Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Wed, 1 Jul 2026 20:48:52 +0200 Subject: [PATCH] adding mic headers, switching to runtime dynamic libloading --- README.md | 12 +- build.zig | 50 +- examples/enumerate.zig | 3 + src/c_includes.h | 1 - src/lib.zig | 858 +++++++++++++++++----- third_party/NOTICES.md | 7 - third_party/miclib.h | 458 ++++++++++++ third_party/scif.h | 1557 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 2695 insertions(+), 251 deletions(-) delete mode 100644 src/c_includes.h delete mode 100644 third_party/NOTICES.md create mode 100644 third_party/miclib.h create mode 100644 third_party/scif.h diff --git a/README.md b/README.md index f200579..68ef94c 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,10 @@ Zig 0.16 wrapper for Intel/CIRCL `miclib.h` / `libmicmgmt`. -This repo does **not** vendor MPSS, `miclib.h`, `scif.h`, `libmicmgmt`, or `libscif`. -Install/build miclib separately, then point Zig at the include/library directories. - ## Build ```sh -zig build \ - -Dmiclib_include=/usr/local/include \ - -Dmiclib_libdir=/usr/local/lib +zig build ``` The default miclib system library name is `micmgmt`, which links `-lmicmgmt`. @@ -35,8 +30,6 @@ Then in your `build.zig`: const miclib_dep = b.dependency("miclib", .{ .target = target, .optimize = optimize, - .miclib_include = "/usr/local/include", - .miclib_libdir = "/usr/local/lib", }); exe.root_module.addImport("miclib", miclib_dep.module("miclib")); @@ -47,6 +40,9 @@ Then in Zig: ```zig const mic = @import("miclib"); +try mic.load(); +defer mic.unload(); + var list = try mic.DeviceList.init(); defer list.deinit(); diff --git a/build.zig b/build.zig index 2153084..9ca33a6 100644 --- a/build.zig +++ b/build.zig @@ -6,48 +6,32 @@ pub fn build(b: *std.Build) void { const use_llvm = b.option(bool, "use-llvm", "LLVM build") orelse (b.release_mode != .off); - const miclib_include = b.option( - []const u8, - "miclib_include", - "Directory containing miclib.h and scif.h. Example: -Dmiclib_include=/usr/local/include", - ); + const c_includes = b.addTranslateC(.{ + .root_source_file = b.path("third_party/miclib.h"), + .target = target, + .optimize = optimize, + .link_libc = true, + }); - const miclib_libdir = b.option( - []const u8, - "miclib_libdir", - "Directory containing libmicmgmt.so/libscif.so. Example: -Dmiclib_libdir=/usr/local/lib", - ); - - const miclib_name = b.option( - []const u8, - "miclib_name", - "System library name for miclib without lib/extension. Default: micmgmt", - ) orelse "micmgmt"; + const miclib_c = c_includes.createModule(); const module = b.addModule("miclib", .{ .root_source_file = b.path("src/lib.zig"), .target = target, .optimize = optimize, .link_libc = true, + .imports = &.{.{ .name = "miclib_c", .module = miclib_c }}, }); - configureMiclibModule(module, miclib_include, miclib_libdir, miclib_name); + module.linkSystemLibrary("dl", .{}); const test_module = b.createModule(.{ .root_source_file = b.path("src/lib.zig"), .target = target, .optimize = optimize, .link_libc = true, + .imports = &.{.{ .name = "miclib_c", .module = miclib_c }}, }); - configureMiclibModule(test_module, miclib_include, miclib_libdir, miclib_name); - - const c_includes = b.addTranslateC(.{ - .root_source_file = b.path("src/c_includes.h"), - .target = target, - .optimize = optimize, - .link_libc = true, - }); - - module.addImport("miclib_c", c_includes.createModule()); + test_module.linkSystemLibrary("dl", .{}); const lib_tests = b.addTest(.{ .root_module = test_module, @@ -76,15 +60,3 @@ pub fn build(b: *std.Build) void { const run_step = b.step("example", "Run examples/enumerate.zig"); run_step.dependOn(&run_enumerate.step); } - -fn configureMiclibModule(module: *std.Build.Module, miclib_include: ?[]const u8, miclib_libdir: ?[]const u8, miclib_name: []const u8) void { - if (miclib_include) |path| - module.addIncludePath(.{ .cwd_relative = path }); - - if (miclib_libdir) |path| - module.addLibraryPath(.{ .cwd_relative = path }); - - module.link_libcpp = true; - module.linkSystemLibrary(miclib_name, .{}); - module.linkSystemLibrary("scif", .{}); -} diff --git a/examples/enumerate.zig b/examples/enumerate.zig index 7b596c1..a3a65bc 100644 --- a/examples/enumerate.zig +++ b/examples/enumerate.zig @@ -2,6 +2,9 @@ const std = @import("std"); const mic = @import("miclib"); pub fn main() !void { + try mic.load(); + defer mic.unload(); + var devices = mic.DeviceList.init() catch |err| { std.debug.print("mic_get_devices failed: {s}\n", .{@errorName(err)}); printLastMicError(); diff --git a/src/c_includes.h b/src/c_includes.h deleted file mode 100644 index 77bc711..0000000 --- a/src/c_includes.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/src/lib.zig b/src/lib.zig index 48a2251..69d543a 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -1,9 +1,11 @@ //! Zig wrapper for Intel/CIRCL miclib. //! -//! This package keeps complete access to the C API through `miclib.c`, while +//! This package keeps access to the C ABI declarations through `miclib.c`, while //! also providing small RAII-style wrappers around the opaque miclib handles. //! //! The wrapped library is the C ABI exported by `miclib.h` / `libmicmgmt`. +//! `libmicmgmt` is loaded at runtime with `std.DynLib`; call `load()` before +//! using the wrappers and `unload()` after every miclib-owned handle is closed. //! Most getters copy into caller-provided buffers to avoid hidden allocation. const std = @import("std"); @@ -37,6 +39,470 @@ pub const flash_op_status: c_int = c.FLASH_OP_STATUS; pub const smc_op_status: c_int = c.SMC_OP_STATUS; pub const default_string_buffer_len: usize = 256; +pub const default_library_name = "libmicmgmt.so"; +pub const default_library_names = [_][]const u8{ + default_library_name, + "libmicmgmt.so.0", +}; + +pub const LoadError = std.DynLib.Error || error{MissingSymbol}; + +fn FnPtr(comptime name: []const u8) type { + return *const @TypeOf(@field(c, name)); +} + +fn loadSymbol(dynlib: *std.DynLib, comptime name: [:0]const u8) LoadError!FnPtr(name) { + return dynlib.lookup(FnPtr(name), name) orelse error.MissingSymbol; +} + +pub const Symbols = struct { + mic_alloc_core_util: FnPtr("mic_alloc_core_util"), + mic_clear_error_string: FnPtr("mic_clear_error_string"), + mic_close_device: FnPtr("mic_close_device"), + mic_enter_maint_mode: FnPtr("mic_enter_maint_mode"), + mic_flash_active_offs: FnPtr("mic_flash_active_offs"), + mic_flash_read_done: FnPtr("mic_flash_read_done"), + mic_flash_read_start: FnPtr("mic_flash_read_start"), + mic_flash_size: FnPtr("mic_flash_size"), + mic_flash_update_done: FnPtr("mic_flash_update_done"), + mic_flash_update_start: FnPtr("mic_flash_update_start"), + mic_flash_version: FnPtr("mic_flash_version"), + mic_free_core_util: FnPtr("mic_free_core_util"), + mic_free_cores_info: FnPtr("mic_free_cores_info"), + mic_free_devices: FnPtr("mic_free_devices"), + mic_free_flash_status_info: FnPtr("mic_free_flash_status_info"), + mic_free_memory_info: FnPtr("mic_free_memory_info"), + mic_free_memory_utilization_info: FnPtr("mic_free_memory_utilization_info"), + mic_free_pci_config: FnPtr("mic_free_pci_config"), + mic_free_power_limit: FnPtr("mic_free_power_limit"), + mic_free_power_utilization_info: FnPtr("mic_free_power_utilization_info"), + mic_free_processor_info: FnPtr("mic_free_processor_info"), + mic_free_thermal_info: FnPtr("mic_free_thermal_info"), + mic_free_throttle_state_info: FnPtr("mic_free_throttle_state_info"), + mic_free_turbo_info: FnPtr("mic_free_turbo_info"), + mic_free_uos_pm_config: FnPtr("mic_free_uos_pm_config"), + mic_free_version_info: FnPtr("mic_free_version_info"), + mic_get_available_memory_size: FnPtr("mic_get_available_memory_size"), + mic_get_bus_number: FnPtr("mic_get_bus_number"), + mic_get_c2x3_power_readings: FnPtr("mic_get_c2x3_power_readings"), + mic_get_c2x3_power_sensor_sts: FnPtr("mic_get_c2x3_power_sensor_sts"), + mic_get_c2x4_power_readings: FnPtr("mic_get_c2x4_power_readings"), + mic_get_c2x4_power_sensor_sts: FnPtr("mic_get_c2x4_power_sensor_sts"), + mic_get_corec6_mode: FnPtr("mic_get_corec6_mode"), + mic_get_cores_count: FnPtr("mic_get_cores_count"), + mic_get_cores_frequency: FnPtr("mic_get_cores_frequency"), + mic_get_cores_info: FnPtr("mic_get_cores_info"), + mic_get_cores_voltage: FnPtr("mic_get_cores_voltage"), + mic_get_cpufreq_mode: FnPtr("mic_get_cpufreq_mode"), + mic_get_device_at_index: FnPtr("mic_get_device_at_index"), + mic_get_device_id: FnPtr("mic_get_device_id"), + mic_get_device_name: FnPtr("mic_get_device_name"), + mic_get_device_number: FnPtr("mic_get_device_number"), + mic_get_device_type: FnPtr("mic_get_device_type"), + mic_get_devices: FnPtr("mic_get_devices"), + mic_get_die_temp: FnPtr("mic_get_die_temp"), + mic_get_ecc_mode: FnPtr("mic_get_ecc_mode"), + mic_get_error_string: FnPtr("mic_get_error_string"), + mic_get_ext_status: FnPtr("mic_get_ext_status"), + mic_get_fan_pwm: FnPtr("mic_get_fan_pwm"), + mic_get_fan_rpm: FnPtr("mic_get_fan_rpm"), + mic_get_fanin_temp: FnPtr("mic_get_fanin_temp"), + mic_get_fanout_temp: FnPtr("mic_get_fanout_temp"), + mic_get_flash_status_info: FnPtr("mic_get_flash_status_info"), + mic_get_flash_vendor_device: FnPtr("mic_get_flash_vendor_device"), + mic_get_flash_version: FnPtr("mic_get_flash_version"), + mic_get_fsc_status: FnPtr("mic_get_fsc_status"), + mic_get_fsc_strap: FnPtr("mic_get_fsc_strap"), + mic_get_gddr_temp: FnPtr("mic_get_gddr_temp"), + mic_get_idle_counters: FnPtr("mic_get_idle_counters"), + mic_get_idle_sum: FnPtr("mic_get_idle_sum"), + mic_get_inst_power_readings: FnPtr("mic_get_inst_power_readings"), + mic_get_inst_power_sensor_sts: FnPtr("mic_get_inst_power_sensor_sts"), + mic_get_jiffy_counter: FnPtr("mic_get_jiffy_counter"), + mic_get_led_alert: FnPtr("mic_get_led_alert"), + mic_get_link_speed: FnPtr("mic_get_link_speed"), + mic_get_link_width: FnPtr("mic_get_link_width"), + mic_get_max_inst_power_readings: FnPtr("mic_get_max_inst_power_readings"), + mic_get_max_inst_power_sensor_sts: FnPtr("mic_get_max_inst_power_sensor_sts"), + mic_get_max_payload: FnPtr("mic_get_max_payload"), + mic_get_max_readreq: FnPtr("mic_get_max_readreq"), + mic_get_memory_buffers_size: FnPtr("mic_get_memory_buffers_size"), + mic_get_memory_density: FnPtr("mic_get_memory_density"), + mic_get_memory_frequency: FnPtr("mic_get_memory_frequency"), + mic_get_memory_info: FnPtr("mic_get_memory_info"), + mic_get_memory_revision: FnPtr("mic_get_memory_revision"), + mic_get_memory_size: FnPtr("mic_get_memory_size"), + mic_get_memory_speed: FnPtr("mic_get_memory_speed"), + mic_get_memory_type: FnPtr("mic_get_memory_type"), + mic_get_memory_utilization_info: FnPtr("mic_get_memory_utilization_info"), + mic_get_memory_vendor: FnPtr("mic_get_memory_vendor"), + mic_get_memory_voltage: FnPtr("mic_get_memory_voltage"), + mic_get_ndevices: FnPtr("mic_get_ndevices"), + mic_get_nice_counters: FnPtr("mic_get_nice_counters"), + mic_get_nice_sum: FnPtr("mic_get_nice_sum"), + mic_get_num_cores: FnPtr("mic_get_num_cores"), + mic_get_pc3_mode: FnPtr("mic_get_pc3_mode"), + mic_get_pc6_mode: FnPtr("mic_get_pc6_mode"), + mic_get_pci_class_code: FnPtr("mic_get_pci_class_code"), + mic_get_pci_config: FnPtr("mic_get_pci_config"), + mic_get_pci_domain_id: FnPtr("mic_get_pci_domain_id"), + mic_get_pcie_power_readings: FnPtr("mic_get_pcie_power_readings"), + mic_get_pcie_power_sensor_sts: FnPtr("mic_get_pcie_power_sensor_sts"), + mic_get_post_code: FnPtr("mic_get_post_code"), + mic_get_power_hmrk: FnPtr("mic_get_power_hmrk"), + mic_get_power_limit: FnPtr("mic_get_power_limit"), + mic_get_power_lmrk: FnPtr("mic_get_power_lmrk"), + mic_get_power_phys_limit: FnPtr("mic_get_power_phys_limit"), + mic_get_power_ttl_active: FnPtr("mic_get_power_ttl_active"), + mic_get_power_ttl_count: FnPtr("mic_get_power_ttl_count"), + mic_get_power_ttl_current_len: FnPtr("mic_get_power_ttl_current_len"), + mic_get_power_ttl_time: FnPtr("mic_get_power_ttl_time"), + mic_get_power_utilization_info: FnPtr("mic_get_power_utilization_info"), + mic_get_processor_family: FnPtr("mic_get_processor_family"), + mic_get_processor_info: FnPtr("mic_get_processor_info"), + mic_get_processor_model: FnPtr("mic_get_processor_model"), + mic_get_processor_stepping: FnPtr("mic_get_processor_stepping"), + mic_get_processor_steppingid: FnPtr("mic_get_processor_steppingid"), + mic_get_processor_type: FnPtr("mic_get_processor_type"), + mic_get_progress: FnPtr("mic_get_progress"), + mic_get_ras_errno: FnPtr("mic_get_ras_errno"), + mic_get_ras_error_string: FnPtr("mic_get_ras_error_string"), + mic_get_revision_id: FnPtr("mic_get_revision_id"), + mic_get_serial_number: FnPtr("mic_get_serial_number"), + mic_get_silicon_sku: FnPtr("mic_get_silicon_sku"), + mic_get_smc_boot_loader_ver: FnPtr("mic_get_smc_boot_loader_ver"), + mic_get_smc_fwversion: FnPtr("mic_get_smc_fwversion"), + mic_get_smc_hwrevision: FnPtr("mic_get_smc_hwrevision"), + mic_get_smc_persistence_flag: FnPtr("mic_get_smc_persistence_flag"), + mic_get_status: FnPtr("mic_get_status"), + mic_get_subsystem_id: FnPtr("mic_get_subsystem_id"), + mic_get_sys_counters: FnPtr("mic_get_sys_counters"), + mic_get_sys_sum: FnPtr("mic_get_sys_sum"), + mic_get_sysfs_attribute: FnPtr("mic_get_sysfs_attribute"), + mic_get_thermal_info: FnPtr("mic_get_thermal_info"), + mic_get_thermal_ttl_active: FnPtr("mic_get_thermal_ttl_active"), + mic_get_thermal_ttl_count: FnPtr("mic_get_thermal_ttl_count"), + mic_get_thermal_ttl_current_len: FnPtr("mic_get_thermal_ttl_current_len"), + mic_get_thermal_ttl_time: FnPtr("mic_get_thermal_ttl_time"), + mic_get_threads_core: FnPtr("mic_get_threads_core"), + mic_get_throttle_state_info: FnPtr("mic_get_throttle_state_info"), + mic_get_tick_count: FnPtr("mic_get_tick_count"), + mic_get_time_window0: FnPtr("mic_get_time_window0"), + mic_get_time_window1: FnPtr("mic_get_time_window1"), + mic_get_total_memory_size: FnPtr("mic_get_total_memory_size"), + mic_get_total_power_readings_w0: FnPtr("mic_get_total_power_readings_w0"), + mic_get_total_power_readings_w1: FnPtr("mic_get_total_power_readings_w1"), + mic_get_total_power_sensor_sts_w0: FnPtr("mic_get_total_power_sensor_sts_w0"), + mic_get_total_power_sensor_sts_w1: FnPtr("mic_get_total_power_sensor_sts_w1"), + mic_get_turbo_mode: FnPtr("mic_get_turbo_mode"), + mic_get_turbo_state: FnPtr("mic_get_turbo_state"), + mic_get_turbo_state_info: FnPtr("mic_get_turbo_state_info"), + mic_get_turbo_state_valid: FnPtr("mic_get_turbo_state_valid"), + mic_get_uos_pm_config: FnPtr("mic_get_uos_pm_config"), + mic_get_uos_version: FnPtr("mic_get_uos_version"), + mic_get_user_counters: FnPtr("mic_get_user_counters"), + mic_get_user_sum: FnPtr("mic_get_user_sum"), + mic_get_uuid: FnPtr("mic_get_uuid"), + mic_get_vccp_current_readings: FnPtr("mic_get_vccp_current_readings"), + mic_get_vccp_current_sensor_sts: FnPtr("mic_get_vccp_current_sensor_sts"), + mic_get_vccp_power_readings: FnPtr("mic_get_vccp_power_readings"), + mic_get_vccp_power_sensor_sts: FnPtr("mic_get_vccp_power_sensor_sts"), + mic_get_vccp_temp: FnPtr("mic_get_vccp_temp"), + mic_get_vccp_voltage_readings: FnPtr("mic_get_vccp_voltage_readings"), + mic_get_vccp_voltage_sensor_sts: FnPtr("mic_get_vccp_voltage_sensor_sts"), + mic_get_vddg_current_readings: FnPtr("mic_get_vddg_current_readings"), + mic_get_vddg_current_sensor_sts: FnPtr("mic_get_vddg_current_sensor_sts"), + mic_get_vddg_power_readings: FnPtr("mic_get_vddg_power_readings"), + mic_get_vddg_power_sensor_sts: FnPtr("mic_get_vddg_power_sensor_sts"), + mic_get_vddg_temp: FnPtr("mic_get_vddg_temp"), + mic_get_vddg_voltage_readings: FnPtr("mic_get_vddg_voltage_readings"), + mic_get_vddg_voltage_sensor_sts: FnPtr("mic_get_vddg_voltage_sensor_sts"), + mic_get_vddq_current_readings: FnPtr("mic_get_vddq_current_readings"), + mic_get_vddq_current_sensor_sts: FnPtr("mic_get_vddq_current_sensor_sts"), + mic_get_vddq_power_readings: FnPtr("mic_get_vddq_power_readings"), + mic_get_vddq_power_sensor_sts: FnPtr("mic_get_vddq_power_sensor_sts"), + mic_get_vddq_temp: FnPtr("mic_get_vddq_temp"), + mic_get_vddq_voltage_readings: FnPtr("mic_get_vddq_voltage_readings"), + mic_get_vddq_voltage_sensor_sts: FnPtr("mic_get_vddq_voltage_sensor_sts"), + mic_get_vendor_id: FnPtr("mic_get_vendor_id"), + mic_get_version_info: FnPtr("mic_get_version_info"), + mic_in_maint_mode: FnPtr("mic_in_maint_mode"), + mic_in_ready_state: FnPtr("mic_in_ready_state"), + mic_is_die_temp_valid: FnPtr("mic_is_die_temp_valid"), + mic_is_fanin_temp_valid: FnPtr("mic_is_fanin_temp_valid"), + mic_is_fanout_temp_valid: FnPtr("mic_is_fanout_temp_valid"), + mic_is_gddr_temp_valid: FnPtr("mic_is_gddr_temp_valid"), + mic_is_ras_avail: FnPtr("mic_is_ras_avail"), + mic_is_smc_boot_loader_ver_supported: FnPtr("mic_is_smc_boot_loader_ver_supported"), + mic_is_vccp_temp_valid: FnPtr("mic_is_vccp_temp_valid"), + mic_is_vddg_temp_valid: FnPtr("mic_is_vddg_temp_valid"), + mic_is_vddq_temp_valid: FnPtr("mic_is_vddq_temp_valid"), + mic_leave_maint_mode: FnPtr("mic_leave_maint_mode"), + mic_open_device: FnPtr("mic_open_device"), + mic_set_ecc_mode_done: FnPtr("mic_set_ecc_mode_done"), + mic_set_ecc_mode_start: FnPtr("mic_set_ecc_mode_start"), + mic_set_led_alert: FnPtr("mic_set_led_alert"), + mic_set_power_limit0: FnPtr("mic_set_power_limit0"), + mic_set_power_limit1: FnPtr("mic_set_power_limit1"), + mic_set_smc_persistence_flag: FnPtr("mic_set_smc_persistence_flag"), + mic_set_turbo_mode: FnPtr("mic_set_turbo_mode"), + mic_update_core_util: FnPtr("mic_update_core_util"), + + pub fn load(dynlib: *std.DynLib) LoadError!Symbols { + return .{ + .mic_alloc_core_util = try loadSymbol(dynlib, "mic_alloc_core_util"), + .mic_clear_error_string = try loadSymbol(dynlib, "mic_clear_error_string"), + .mic_close_device = try loadSymbol(dynlib, "mic_close_device"), + .mic_enter_maint_mode = try loadSymbol(dynlib, "mic_enter_maint_mode"), + .mic_flash_active_offs = try loadSymbol(dynlib, "mic_flash_active_offs"), + .mic_flash_read_done = try loadSymbol(dynlib, "mic_flash_read_done"), + .mic_flash_read_start = try loadSymbol(dynlib, "mic_flash_read_start"), + .mic_flash_size = try loadSymbol(dynlib, "mic_flash_size"), + .mic_flash_update_done = try loadSymbol(dynlib, "mic_flash_update_done"), + .mic_flash_update_start = try loadSymbol(dynlib, "mic_flash_update_start"), + .mic_flash_version = try loadSymbol(dynlib, "mic_flash_version"), + .mic_free_core_util = try loadSymbol(dynlib, "mic_free_core_util"), + .mic_free_cores_info = try loadSymbol(dynlib, "mic_free_cores_info"), + .mic_free_devices = try loadSymbol(dynlib, "mic_free_devices"), + .mic_free_flash_status_info = try loadSymbol(dynlib, "mic_free_flash_status_info"), + .mic_free_memory_info = try loadSymbol(dynlib, "mic_free_memory_info"), + .mic_free_memory_utilization_info = try loadSymbol(dynlib, "mic_free_memory_utilization_info"), + .mic_free_pci_config = try loadSymbol(dynlib, "mic_free_pci_config"), + .mic_free_power_limit = try loadSymbol(dynlib, "mic_free_power_limit"), + .mic_free_power_utilization_info = try loadSymbol(dynlib, "mic_free_power_utilization_info"), + .mic_free_processor_info = try loadSymbol(dynlib, "mic_free_processor_info"), + .mic_free_thermal_info = try loadSymbol(dynlib, "mic_free_thermal_info"), + .mic_free_throttle_state_info = try loadSymbol(dynlib, "mic_free_throttle_state_info"), + .mic_free_turbo_info = try loadSymbol(dynlib, "mic_free_turbo_info"), + .mic_free_uos_pm_config = try loadSymbol(dynlib, "mic_free_uos_pm_config"), + .mic_free_version_info = try loadSymbol(dynlib, "mic_free_version_info"), + .mic_get_available_memory_size = try loadSymbol(dynlib, "mic_get_available_memory_size"), + .mic_get_bus_number = try loadSymbol(dynlib, "mic_get_bus_number"), + .mic_get_c2x3_power_readings = try loadSymbol(dynlib, "mic_get_c2x3_power_readings"), + .mic_get_c2x3_power_sensor_sts = try loadSymbol(dynlib, "mic_get_c2x3_power_sensor_sts"), + .mic_get_c2x4_power_readings = try loadSymbol(dynlib, "mic_get_c2x4_power_readings"), + .mic_get_c2x4_power_sensor_sts = try loadSymbol(dynlib, "mic_get_c2x4_power_sensor_sts"), + .mic_get_corec6_mode = try loadSymbol(dynlib, "mic_get_corec6_mode"), + .mic_get_cores_count = try loadSymbol(dynlib, "mic_get_cores_count"), + .mic_get_cores_frequency = try loadSymbol(dynlib, "mic_get_cores_frequency"), + .mic_get_cores_info = try loadSymbol(dynlib, "mic_get_cores_info"), + .mic_get_cores_voltage = try loadSymbol(dynlib, "mic_get_cores_voltage"), + .mic_get_cpufreq_mode = try loadSymbol(dynlib, "mic_get_cpufreq_mode"), + .mic_get_device_at_index = try loadSymbol(dynlib, "mic_get_device_at_index"), + .mic_get_device_id = try loadSymbol(dynlib, "mic_get_device_id"), + .mic_get_device_name = try loadSymbol(dynlib, "mic_get_device_name"), + .mic_get_device_number = try loadSymbol(dynlib, "mic_get_device_number"), + .mic_get_device_type = try loadSymbol(dynlib, "mic_get_device_type"), + .mic_get_devices = try loadSymbol(dynlib, "mic_get_devices"), + .mic_get_die_temp = try loadSymbol(dynlib, "mic_get_die_temp"), + .mic_get_ecc_mode = try loadSymbol(dynlib, "mic_get_ecc_mode"), + .mic_get_error_string = try loadSymbol(dynlib, "mic_get_error_string"), + .mic_get_ext_status = try loadSymbol(dynlib, "mic_get_ext_status"), + .mic_get_fan_pwm = try loadSymbol(dynlib, "mic_get_fan_pwm"), + .mic_get_fan_rpm = try loadSymbol(dynlib, "mic_get_fan_rpm"), + .mic_get_fanin_temp = try loadSymbol(dynlib, "mic_get_fanin_temp"), + .mic_get_fanout_temp = try loadSymbol(dynlib, "mic_get_fanout_temp"), + .mic_get_flash_status_info = try loadSymbol(dynlib, "mic_get_flash_status_info"), + .mic_get_flash_vendor_device = try loadSymbol(dynlib, "mic_get_flash_vendor_device"), + .mic_get_flash_version = try loadSymbol(dynlib, "mic_get_flash_version"), + .mic_get_fsc_status = try loadSymbol(dynlib, "mic_get_fsc_status"), + .mic_get_fsc_strap = try loadSymbol(dynlib, "mic_get_fsc_strap"), + .mic_get_gddr_temp = try loadSymbol(dynlib, "mic_get_gddr_temp"), + .mic_get_idle_counters = try loadSymbol(dynlib, "mic_get_idle_counters"), + .mic_get_idle_sum = try loadSymbol(dynlib, "mic_get_idle_sum"), + .mic_get_inst_power_readings = try loadSymbol(dynlib, "mic_get_inst_power_readings"), + .mic_get_inst_power_sensor_sts = try loadSymbol(dynlib, "mic_get_inst_power_sensor_sts"), + .mic_get_jiffy_counter = try loadSymbol(dynlib, "mic_get_jiffy_counter"), + .mic_get_led_alert = try loadSymbol(dynlib, "mic_get_led_alert"), + .mic_get_link_speed = try loadSymbol(dynlib, "mic_get_link_speed"), + .mic_get_link_width = try loadSymbol(dynlib, "mic_get_link_width"), + .mic_get_max_inst_power_readings = try loadSymbol(dynlib, "mic_get_max_inst_power_readings"), + .mic_get_max_inst_power_sensor_sts = try loadSymbol(dynlib, "mic_get_max_inst_power_sensor_sts"), + .mic_get_max_payload = try loadSymbol(dynlib, "mic_get_max_payload"), + .mic_get_max_readreq = try loadSymbol(dynlib, "mic_get_max_readreq"), + .mic_get_memory_buffers_size = try loadSymbol(dynlib, "mic_get_memory_buffers_size"), + .mic_get_memory_density = try loadSymbol(dynlib, "mic_get_memory_density"), + .mic_get_memory_frequency = try loadSymbol(dynlib, "mic_get_memory_frequency"), + .mic_get_memory_info = try loadSymbol(dynlib, "mic_get_memory_info"), + .mic_get_memory_revision = try loadSymbol(dynlib, "mic_get_memory_revision"), + .mic_get_memory_size = try loadSymbol(dynlib, "mic_get_memory_size"), + .mic_get_memory_speed = try loadSymbol(dynlib, "mic_get_memory_speed"), + .mic_get_memory_type = try loadSymbol(dynlib, "mic_get_memory_type"), + .mic_get_memory_utilization_info = try loadSymbol(dynlib, "mic_get_memory_utilization_info"), + .mic_get_memory_vendor = try loadSymbol(dynlib, "mic_get_memory_vendor"), + .mic_get_memory_voltage = try loadSymbol(dynlib, "mic_get_memory_voltage"), + .mic_get_ndevices = try loadSymbol(dynlib, "mic_get_ndevices"), + .mic_get_nice_counters = try loadSymbol(dynlib, "mic_get_nice_counters"), + .mic_get_nice_sum = try loadSymbol(dynlib, "mic_get_nice_sum"), + .mic_get_num_cores = try loadSymbol(dynlib, "mic_get_num_cores"), + .mic_get_pc3_mode = try loadSymbol(dynlib, "mic_get_pc3_mode"), + .mic_get_pc6_mode = try loadSymbol(dynlib, "mic_get_pc6_mode"), + .mic_get_pci_class_code = try loadSymbol(dynlib, "mic_get_pci_class_code"), + .mic_get_pci_config = try loadSymbol(dynlib, "mic_get_pci_config"), + .mic_get_pci_domain_id = try loadSymbol(dynlib, "mic_get_pci_domain_id"), + .mic_get_pcie_power_readings = try loadSymbol(dynlib, "mic_get_pcie_power_readings"), + .mic_get_pcie_power_sensor_sts = try loadSymbol(dynlib, "mic_get_pcie_power_sensor_sts"), + .mic_get_post_code = try loadSymbol(dynlib, "mic_get_post_code"), + .mic_get_power_hmrk = try loadSymbol(dynlib, "mic_get_power_hmrk"), + .mic_get_power_limit = try loadSymbol(dynlib, "mic_get_power_limit"), + .mic_get_power_lmrk = try loadSymbol(dynlib, "mic_get_power_lmrk"), + .mic_get_power_phys_limit = try loadSymbol(dynlib, "mic_get_power_phys_limit"), + .mic_get_power_ttl_active = try loadSymbol(dynlib, "mic_get_power_ttl_active"), + .mic_get_power_ttl_count = try loadSymbol(dynlib, "mic_get_power_ttl_count"), + .mic_get_power_ttl_current_len = try loadSymbol(dynlib, "mic_get_power_ttl_current_len"), + .mic_get_power_ttl_time = try loadSymbol(dynlib, "mic_get_power_ttl_time"), + .mic_get_power_utilization_info = try loadSymbol(dynlib, "mic_get_power_utilization_info"), + .mic_get_processor_family = try loadSymbol(dynlib, "mic_get_processor_family"), + .mic_get_processor_info = try loadSymbol(dynlib, "mic_get_processor_info"), + .mic_get_processor_model = try loadSymbol(dynlib, "mic_get_processor_model"), + .mic_get_processor_stepping = try loadSymbol(dynlib, "mic_get_processor_stepping"), + .mic_get_processor_steppingid = try loadSymbol(dynlib, "mic_get_processor_steppingid"), + .mic_get_processor_type = try loadSymbol(dynlib, "mic_get_processor_type"), + .mic_get_progress = try loadSymbol(dynlib, "mic_get_progress"), + .mic_get_ras_errno = try loadSymbol(dynlib, "mic_get_ras_errno"), + .mic_get_ras_error_string = try loadSymbol(dynlib, "mic_get_ras_error_string"), + .mic_get_revision_id = try loadSymbol(dynlib, "mic_get_revision_id"), + .mic_get_serial_number = try loadSymbol(dynlib, "mic_get_serial_number"), + .mic_get_silicon_sku = try loadSymbol(dynlib, "mic_get_silicon_sku"), + .mic_get_smc_boot_loader_ver = try loadSymbol(dynlib, "mic_get_smc_boot_loader_ver"), + .mic_get_smc_fwversion = try loadSymbol(dynlib, "mic_get_smc_fwversion"), + .mic_get_smc_hwrevision = try loadSymbol(dynlib, "mic_get_smc_hwrevision"), + .mic_get_smc_persistence_flag = try loadSymbol(dynlib, "mic_get_smc_persistence_flag"), + .mic_get_status = try loadSymbol(dynlib, "mic_get_status"), + .mic_get_subsystem_id = try loadSymbol(dynlib, "mic_get_subsystem_id"), + .mic_get_sys_counters = try loadSymbol(dynlib, "mic_get_sys_counters"), + .mic_get_sys_sum = try loadSymbol(dynlib, "mic_get_sys_sum"), + .mic_get_sysfs_attribute = try loadSymbol(dynlib, "mic_get_sysfs_attribute"), + .mic_get_thermal_info = try loadSymbol(dynlib, "mic_get_thermal_info"), + .mic_get_thermal_ttl_active = try loadSymbol(dynlib, "mic_get_thermal_ttl_active"), + .mic_get_thermal_ttl_count = try loadSymbol(dynlib, "mic_get_thermal_ttl_count"), + .mic_get_thermal_ttl_current_len = try loadSymbol(dynlib, "mic_get_thermal_ttl_current_len"), + .mic_get_thermal_ttl_time = try loadSymbol(dynlib, "mic_get_thermal_ttl_time"), + .mic_get_threads_core = try loadSymbol(dynlib, "mic_get_threads_core"), + .mic_get_throttle_state_info = try loadSymbol(dynlib, "mic_get_throttle_state_info"), + .mic_get_tick_count = try loadSymbol(dynlib, "mic_get_tick_count"), + .mic_get_time_window0 = try loadSymbol(dynlib, "mic_get_time_window0"), + .mic_get_time_window1 = try loadSymbol(dynlib, "mic_get_time_window1"), + .mic_get_total_memory_size = try loadSymbol(dynlib, "mic_get_total_memory_size"), + .mic_get_total_power_readings_w0 = try loadSymbol(dynlib, "mic_get_total_power_readings_w0"), + .mic_get_total_power_readings_w1 = try loadSymbol(dynlib, "mic_get_total_power_readings_w1"), + .mic_get_total_power_sensor_sts_w0 = try loadSymbol(dynlib, "mic_get_total_power_sensor_sts_w0"), + .mic_get_total_power_sensor_sts_w1 = try loadSymbol(dynlib, "mic_get_total_power_sensor_sts_w1"), + .mic_get_turbo_mode = try loadSymbol(dynlib, "mic_get_turbo_mode"), + .mic_get_turbo_state = try loadSymbol(dynlib, "mic_get_turbo_state"), + .mic_get_turbo_state_info = try loadSymbol(dynlib, "mic_get_turbo_state_info"), + .mic_get_turbo_state_valid = try loadSymbol(dynlib, "mic_get_turbo_state_valid"), + .mic_get_uos_pm_config = try loadSymbol(dynlib, "mic_get_uos_pm_config"), + .mic_get_uos_version = try loadSymbol(dynlib, "mic_get_uos_version"), + .mic_get_user_counters = try loadSymbol(dynlib, "mic_get_user_counters"), + .mic_get_user_sum = try loadSymbol(dynlib, "mic_get_user_sum"), + .mic_get_uuid = try loadSymbol(dynlib, "mic_get_uuid"), + .mic_get_vccp_current_readings = try loadSymbol(dynlib, "mic_get_vccp_current_readings"), + .mic_get_vccp_current_sensor_sts = try loadSymbol(dynlib, "mic_get_vccp_current_sensor_sts"), + .mic_get_vccp_power_readings = try loadSymbol(dynlib, "mic_get_vccp_power_readings"), + .mic_get_vccp_power_sensor_sts = try loadSymbol(dynlib, "mic_get_vccp_power_sensor_sts"), + .mic_get_vccp_temp = try loadSymbol(dynlib, "mic_get_vccp_temp"), + .mic_get_vccp_voltage_readings = try loadSymbol(dynlib, "mic_get_vccp_voltage_readings"), + .mic_get_vccp_voltage_sensor_sts = try loadSymbol(dynlib, "mic_get_vccp_voltage_sensor_sts"), + .mic_get_vddg_current_readings = try loadSymbol(dynlib, "mic_get_vddg_current_readings"), + .mic_get_vddg_current_sensor_sts = try loadSymbol(dynlib, "mic_get_vddg_current_sensor_sts"), + .mic_get_vddg_power_readings = try loadSymbol(dynlib, "mic_get_vddg_power_readings"), + .mic_get_vddg_power_sensor_sts = try loadSymbol(dynlib, "mic_get_vddg_power_sensor_sts"), + .mic_get_vddg_temp = try loadSymbol(dynlib, "mic_get_vddg_temp"), + .mic_get_vddg_voltage_readings = try loadSymbol(dynlib, "mic_get_vddg_voltage_readings"), + .mic_get_vddg_voltage_sensor_sts = try loadSymbol(dynlib, "mic_get_vddg_voltage_sensor_sts"), + .mic_get_vddq_current_readings = try loadSymbol(dynlib, "mic_get_vddq_current_readings"), + .mic_get_vddq_current_sensor_sts = try loadSymbol(dynlib, "mic_get_vddq_current_sensor_sts"), + .mic_get_vddq_power_readings = try loadSymbol(dynlib, "mic_get_vddq_power_readings"), + .mic_get_vddq_power_sensor_sts = try loadSymbol(dynlib, "mic_get_vddq_power_sensor_sts"), + .mic_get_vddq_temp = try loadSymbol(dynlib, "mic_get_vddq_temp"), + .mic_get_vddq_voltage_readings = try loadSymbol(dynlib, "mic_get_vddq_voltage_readings"), + .mic_get_vddq_voltage_sensor_sts = try loadSymbol(dynlib, "mic_get_vddq_voltage_sensor_sts"), + .mic_get_vendor_id = try loadSymbol(dynlib, "mic_get_vendor_id"), + .mic_get_version_info = try loadSymbol(dynlib, "mic_get_version_info"), + .mic_in_maint_mode = try loadSymbol(dynlib, "mic_in_maint_mode"), + .mic_in_ready_state = try loadSymbol(dynlib, "mic_in_ready_state"), + .mic_is_die_temp_valid = try loadSymbol(dynlib, "mic_is_die_temp_valid"), + .mic_is_fanin_temp_valid = try loadSymbol(dynlib, "mic_is_fanin_temp_valid"), + .mic_is_fanout_temp_valid = try loadSymbol(dynlib, "mic_is_fanout_temp_valid"), + .mic_is_gddr_temp_valid = try loadSymbol(dynlib, "mic_is_gddr_temp_valid"), + .mic_is_ras_avail = try loadSymbol(dynlib, "mic_is_ras_avail"), + .mic_is_smc_boot_loader_ver_supported = try loadSymbol(dynlib, "mic_is_smc_boot_loader_ver_supported"), + .mic_is_vccp_temp_valid = try loadSymbol(dynlib, "mic_is_vccp_temp_valid"), + .mic_is_vddg_temp_valid = try loadSymbol(dynlib, "mic_is_vddg_temp_valid"), + .mic_is_vddq_temp_valid = try loadSymbol(dynlib, "mic_is_vddq_temp_valid"), + .mic_leave_maint_mode = try loadSymbol(dynlib, "mic_leave_maint_mode"), + .mic_open_device = try loadSymbol(dynlib, "mic_open_device"), + .mic_set_ecc_mode_done = try loadSymbol(dynlib, "mic_set_ecc_mode_done"), + .mic_set_ecc_mode_start = try loadSymbol(dynlib, "mic_set_ecc_mode_start"), + .mic_set_led_alert = try loadSymbol(dynlib, "mic_set_led_alert"), + .mic_set_power_limit0 = try loadSymbol(dynlib, "mic_set_power_limit0"), + .mic_set_power_limit1 = try loadSymbol(dynlib, "mic_set_power_limit1"), + .mic_set_smc_persistence_flag = try loadSymbol(dynlib, "mic_set_smc_persistence_flag"), + .mic_set_turbo_mode = try loadSymbol(dynlib, "mic_set_turbo_mode"), + .mic_update_core_util = try loadSymbol(dynlib, "mic_update_core_util"), + }; + } +}; + +pub const DynamicLibrary = struct { + dynlib: std.DynLib, + symbols: Symbols, + + pub fn open(path: []const u8) LoadError!DynamicLibrary { + var dynlib = try std.DynLib.open(path); + errdefer dynlib.close(); + + return .{ + .dynlib = dynlib, + .symbols = try Symbols.load(&dynlib), + }; + } + + pub fn close(self: *DynamicLibrary) void { + self.dynlib.close(); + self.* = undefined; + } +}; + +var loaded_library: ?DynamicLibrary = null; + +pub fn load() LoadError!void { + if (loaded_library != null) return; + + var first_error: ?LoadError = null; + for (default_library_names) |name| { + loadPath(name) catch |err| { + if (first_error == null) first_error = err; + continue; + }; + return; + } + + return first_error orelse error.FileNotFound; +} + +pub fn loadPath(path: []const u8) LoadError!void { + if (loaded_library != null) return; + loaded_library = try DynamicLibrary.open(path); +} + +pub fn unload() void { + if (loaded_library) |*library| { + library.close(); + loaded_library = null; + } +} + +pub fn isLoaded() bool { + return loaded_library != null; +} + +fn micApi() *const Symbols { + if (loaded_library) |*library| return &library.symbols; + @panic("miclib.load() or miclib.loadPath() must be called before using libmicmgmt symbols"); +} + pub fn isFlashOperationStatus(status: c_int) bool { return (status & c.FLASH_OP_STATUS) != 0; } @@ -72,19 +538,19 @@ pub fn check(result: c_int) MicError!void { } pub fn lastErrorString() []const u8 { - return cString(c.mic_get_error_string()); + return cString(micApi().mic_get_error_string()); } pub fn clearLastErrorString() MicError!void { - try check(c.mic_clear_error_string()); + try check(micApi().mic_clear_error_string()); } pub fn rasErrno() c_int { - return c.mic_get_ras_errno(); + return micApi().mic_get_ras_errno(); } pub fn rasErrorString(ras_errno: c_int) []const u8 { - return cString(c.mic_get_ras_error_string(ras_errno)); + return cString(micApi().mic_get_ras_error_string(ras_errno)); } pub fn cString(ptr: [*c]const u8) []const u8 { @@ -114,21 +580,21 @@ fn usizeToCInt(value: usize) MicError!c_int { return @as(c_int, @intCast(value)); } -fn getValue(comptime T: type, comptime func: anytype, handle: anytype) MicError!T { +fn getValue(comptime T: type, func: anytype, handle: anytype) MicError!T { var value: T = 0; try check(func(handle, &value)); return value; } -fn getBoolInt(comptime func: anytype, handle: anytype) MicError!bool { +fn getBoolInt(func: anytype, handle: anytype) MicError!bool { return (try getValue(c_int, func, handle)) != 0; } -fn getBoolU32(comptime func: anytype, handle: anytype) MicError!bool { +fn getBoolU32(func: anytype, handle: anytype) MicError!bool { return (try getValue(u32, func, handle)) != 0; } -fn getString(comptime func: anytype, handle: anytype, buffer: []u8) MicError![]const u8 { +fn getString(func: anytype, handle: anytype, buffer: []u8) MicError![]const u8 { if (buffer.len == 0) return error.OutOfRange; var size: usize = buffer.len; @@ -141,23 +607,23 @@ pub const DeviceList = struct { pub fn init() MicError!DeviceList { var handle: ?*c.struct_mic_devices_list = null; - try check(c.mic_get_devices(&handle)); + try check(micApi().mic_get_devices(&handle)); return .{ .handle = try ensureHandle(c.struct_mic_devices_list, handle) }; } pub fn deinit(self: *DeviceList) void { - _ = c.mic_free_devices(self.handle); + _ = micApi().mic_free_devices(self.handle); } pub fn count(self: DeviceList) MicError!usize { var ndevices: c_int = 0; - try check(c.mic_get_ndevices(self.handle, &ndevices)); + try check(micApi().mic_get_ndevices(self.handle, &ndevices)); return intToUsize(ndevices); } pub fn deviceAtIndex(self: DeviceList, index: usize) MicError!u32 { var device: c_int = 0; - try check(c.mic_get_device_at_index(self.handle, try usizeToCInt(index), &device)); + try check(micApi().mic_get_device_at_index(self.handle, try usizeToCInt(index), &device)); if (device < 0) return error.OutOfRange; return @as(u32, @intCast(device)); } @@ -168,55 +634,55 @@ pub const Device = struct { pub fn open(device_num: u32) MicError!Device { var handle: ?*c.struct_mic_device = null; - try check(c.mic_open_device(&handle, device_num)); + try check(micApi().mic_open_device(&handle, device_num)); return .{ .handle = try ensureHandle(c.struct_mic_device, handle) }; } pub fn deinit(self: *Device) void { - _ = c.mic_close_device(self.handle); + _ = micApi().mic_close_device(self.handle); } pub fn enterMaintMode(self: Device) MicError!void { - try check(c.mic_enter_maint_mode(self.handle)); + try check(micApi().mic_enter_maint_mode(self.handle)); } pub fn leaveMaintMode(self: Device) MicError!void { - try check(c.mic_leave_maint_mode(self.handle)); + try check(micApi().mic_leave_maint_mode(self.handle)); } pub fn inMaintMode(self: Device) MicError!bool { - return getBoolInt(c.mic_in_maint_mode, self.handle); + return getBoolInt(micApi().mic_in_maint_mode, self.handle); } pub fn inReadyState(self: Device) MicError!bool { - return getBoolInt(c.mic_in_ready_state, self.handle); + return getBoolInt(micApi().mic_in_ready_state, self.handle); } pub fn postCode(self: Device, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_post_code, self.handle, buffer); + return getString(micApi().mic_get_post_code, self.handle, buffer); } pub fn deviceType(self: Device) MicError!u32 { - return getValue(u32, c.mic_get_device_type, self.handle); + return getValue(u32, micApi().mic_get_device_type, self.handle); } pub fn name(self: Device) []const u8 { - return cString(c.mic_get_device_name(self.handle)); + return cString(micApi().mic_get_device_name(self.handle)); } pub fn siliconSku(self: Device, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_silicon_sku, self.handle, buffer); + return getString(micApi().mic_get_silicon_sku, self.handle, buffer); } pub fn serialNumber(self: Device, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_serial_number, self.handle, buffer); + return getString(micApi().mic_get_serial_number, self.handle, buffer); } pub fn uuid(self: Device, buffer: []u8) MicError![]const u8 { if (buffer.len == 0) return error.OutOfRange; var size: usize = buffer.len; - try check(c.mic_get_uuid(self.handle, buffer.ptr, &size)); + try check(micApi().mic_get_uuid(self.handle, buffer.ptr, &size)); return buffer[0..@min(size, buffer.len)]; } @@ -224,50 +690,50 @@ pub const Device = struct { if (buffer.len == 0) return error.OutOfRange; var size: usize = buffer.len; - try check(c.mic_get_sysfs_attribute(self.handle, entry.ptr, buffer.ptr, &size)); + try check(micApi().mic_get_sysfs_attribute(self.handle, entry.ptr, buffer.ptr, &size)); return trimCString(buffer[0..@min(size, buffer.len)]); } pub fn isRasAvailable(self: Device) MicError!bool { - return getBoolInt(c.mic_is_ras_avail, self.handle); + return getBoolInt(micApi().mic_is_ras_avail, self.handle); } pub fn flashUpdateStart(self: Device, image: []const u8) MicError!FlashOperation { var handle: ?*c.struct_mic_flash_op = null; const image_ptr: ?*anyopaque = @ptrCast(@constCast(image.ptr)); - try check(c.mic_flash_update_start(self.handle, image_ptr, image.len, &handle)); + try check(micApi().mic_flash_update_start(self.handle, image_ptr, image.len, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_flash_op, handle), .kind = .update }; } pub fn flashReadStart(self: Device, buffer: []u8) MicError!FlashOperation { var handle: ?*c.struct_mic_flash_op = null; const buffer_ptr: ?*anyopaque = @ptrCast(buffer.ptr); - try check(c.mic_flash_read_start(self.handle, buffer_ptr, buffer.len, &handle)); + try check(micApi().mic_flash_read_start(self.handle, buffer_ptr, buffer.len, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_flash_op, handle), .kind = .read }; } pub fn setEccModeStart(self: Device, ecc_enabled: u16) MicError!FlashOperation { var handle: ?*c.struct_mic_flash_op = null; - try check(c.mic_set_ecc_mode_start(self.handle, ecc_enabled, &handle)); + try check(micApi().mic_set_ecc_mode_start(self.handle, ecc_enabled, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_flash_op, handle), .kind = .set_ecc }; } pub fn flashVendorDevice(self: Device, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_flash_vendor_device, self.handle, buffer); + return getString(micApi().mic_get_flash_vendor_device, self.handle, buffer); } pub fn flashSize(self: Device) MicError!usize { - return getValue(usize, c.mic_flash_size, self.handle); + return getValue(usize, micApi().mic_flash_size, self.handle); } pub fn flashActiveOffset(self: Device) MicError!c.off_t { - return getValue(c.off_t, c.mic_flash_active_offs, self.handle); + return getValue(c.off_t, micApi().mic_flash_active_offs, self.handle); } pub fn flashVersion(self: Device, image: ?*anyopaque, buffer: []u8) MicError![]const u8 { if (buffer.len == 0) return error.OutOfRange; - try check(c.mic_flash_version(self.handle, image, buffer.ptr, buffer.len)); + try check(micApi().mic_flash_version(self.handle, image, buffer.ptr, buffer.len)); return trimCString(buffer); } @@ -308,12 +774,12 @@ pub const Device = struct { } pub fn ledAlert(self: Device) MicError!u32 { - return getValue(u32, c.mic_get_led_alert, self.handle); + return getValue(u32, micApi().mic_get_led_alert, self.handle); } pub fn setLedAlert(self: Device, value: u32) MicError!void { var mutable_value = value; - try check(c.mic_set_led_alert(self.handle, &mutable_value)); + try check(micApi().mic_set_led_alert(self.handle, &mutable_value)); } pub fn turboStateInfo(self: Device) MicError!TurboInfo { @@ -322,7 +788,7 @@ pub const Device = struct { pub fn setTurboMode(self: Device, mode: u32) MicError!void { var mutable_mode = mode; - try check(c.mic_set_turbo_mode(self.handle, &mutable_mode)); + try check(micApi().mic_set_turbo_mode(self.handle, &mutable_mode)); } pub fn throttleStateInfo(self: Device) MicError!ThrottleStateInfo { @@ -334,19 +800,19 @@ pub const Device = struct { } pub fn smcPersistenceFlag(self: Device) MicError!bool { - return getBoolInt(c.mic_get_smc_persistence_flag, self.handle); + return getBoolInt(micApi().mic_get_smc_persistence_flag, self.handle); } pub fn setSmcPersistenceFlag(self: Device, persist: bool) MicError!void { - try check(c.mic_set_smc_persistence_flag(self.handle, @as(c_int, @intFromBool(persist)))); + try check(micApi().mic_set_smc_persistence_flag(self.handle, @as(c_int, @intFromBool(persist)))); } pub fn setPowerLimit0(self: Device, power: u32, time_window: u32) MicError!void { - try check(c.mic_set_power_limit0(self.handle, power, time_window)); + try check(micApi().mic_set_power_limit0(self.handle, power, time_window)); } pub fn setPowerLimit1(self: Device, power: u32, time_window: u32) MicError!void { - try check(c.mic_set_power_limit1(self.handle, power, time_window)); + try check(micApi().mic_set_power_limit1(self.handle, power, time_window)); } }; @@ -369,9 +835,9 @@ pub const FlashOperation = struct { if (self.completed) return; const result = switch (self.kind) { - .update => c.mic_flash_update_done(self.handle), - .read => c.mic_flash_read_done(self.handle), - .set_ecc => c.mic_set_ecc_mode_done(self.handle), + .update => micApi().mic_flash_update_done(self.handle), + .read => micApi().mic_flash_read_done(self.handle), + .set_ecc => micApi().mic_set_ecc_mode_done(self.handle), }; try check(result); self.completed = true; @@ -379,7 +845,7 @@ pub const FlashOperation = struct { pub fn statusInfo(self: FlashOperation) MicError!FlashStatusInfo { var handle: ?*c.struct_mic_flash_status_info = null; - try check(c.mic_get_flash_status_info(self.handle, &handle)); + try check(micApi().mic_get_flash_status_info(self.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_flash_status_info, handle) }; } }; @@ -388,19 +854,19 @@ pub const FlashStatusInfo = struct { handle: *c.struct_mic_flash_status_info, pub fn deinit(self: *FlashStatusInfo) void { - _ = c.mic_free_flash_status_info(self.handle); + _ = micApi().mic_free_flash_status_info(self.handle); } pub fn progress(self: FlashStatusInfo) MicError!u32 { - return getValue(u32, c.mic_get_progress, self.handle); + return getValue(u32, micApi().mic_get_progress, self.handle); } pub fn status(self: FlashStatusInfo) MicError!c_int { - return getValue(c_int, c.mic_get_status, self.handle); + return getValue(c_int, micApi().mic_get_status, self.handle); } pub fn extendedStatus(self: FlashStatusInfo) MicError!c_int { - return getValue(c_int, c.mic_get_ext_status, self.handle); + return getValue(c_int, micApi().mic_get_ext_status, self.handle); } }; @@ -409,60 +875,60 @@ pub const PciConfig = struct { pub fn init(device: Device) MicError!PciConfig { var handle: ?*c.struct_mic_pci_config = null; - try check(c.mic_get_pci_config(device.handle, &handle)); + try check(micApi().mic_get_pci_config(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_pci_config, handle) }; } pub fn deinit(self: *PciConfig) void { - _ = c.mic_free_pci_config(self.handle); + _ = micApi().mic_free_pci_config(self.handle); } pub fn domainId(self: PciConfig) MicError!u16 { - return getValue(u16, c.mic_get_pci_domain_id, self.handle); + return getValue(u16, micApi().mic_get_pci_domain_id, self.handle); } pub fn busNumber(self: PciConfig) MicError!u16 { - return getValue(u16, c.mic_get_bus_number, self.handle); + return getValue(u16, micApi().mic_get_bus_number, self.handle); } pub fn deviceNumber(self: PciConfig) MicError!u16 { - return getValue(u16, c.mic_get_device_number, self.handle); + return getValue(u16, micApi().mic_get_device_number, self.handle); } pub fn vendorId(self: PciConfig) MicError!u16 { - return getValue(u16, c.mic_get_vendor_id, self.handle); + return getValue(u16, micApi().mic_get_vendor_id, self.handle); } pub fn deviceId(self: PciConfig) MicError!u16 { - return getValue(u16, c.mic_get_device_id, self.handle); + return getValue(u16, micApi().mic_get_device_id, self.handle); } pub fn revisionId(self: PciConfig) MicError!u8 { - return getValue(u8, c.mic_get_revision_id, self.handle); + return getValue(u8, micApi().mic_get_revision_id, self.handle); } pub fn subsystemId(self: PciConfig) MicError!u16 { - return getValue(u16, c.mic_get_subsystem_id, self.handle); + return getValue(u16, micApi().mic_get_subsystem_id, self.handle); } pub fn linkSpeed(self: PciConfig, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_link_speed, self.handle, buffer); + return getString(micApi().mic_get_link_speed, self.handle, buffer); } pub fn linkWidth(self: PciConfig) MicError!u32 { - return getValue(u32, c.mic_get_link_width, self.handle); + return getValue(u32, micApi().mic_get_link_width, self.handle); } pub fn maxPayload(self: PciConfig) MicError!u32 { - return getValue(u32, c.mic_get_max_payload, self.handle); + return getValue(u32, micApi().mic_get_max_payload, self.handle); } pub fn maxReadRequest(self: PciConfig) MicError!u32 { - return getValue(u32, c.mic_get_max_readreq, self.handle); + return getValue(u32, micApi().mic_get_max_readreq, self.handle); } pub fn classCode(self: PciConfig, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_pci_class_code, self.handle, buffer); + return getString(micApi().mic_get_pci_class_code, self.handle, buffer); } }; @@ -471,96 +937,96 @@ pub const ThermalInfo = struct { pub fn init(device: Device) MicError!ThermalInfo { var handle: ?*c.struct_mic_thermal_info = null; - try check(c.mic_get_thermal_info(device.handle, &handle)); + try check(micApi().mic_get_thermal_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_thermal_info, handle) }; } pub fn deinit(self: *ThermalInfo) void { - _ = c.mic_free_thermal_info(self.handle); + _ = micApi().mic_free_thermal_info(self.handle); } pub fn smcHardwareRevision(self: ThermalInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_smc_hwrevision, self.handle, buffer); + return getString(micApi().mic_get_smc_hwrevision, self.handle, buffer); } pub fn smcFirmwareVersion(self: ThermalInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_smc_fwversion, self.handle, buffer); + return getString(micApi().mic_get_smc_fwversion, self.handle, buffer); } pub fn isSmcBootLoaderVersionSupported(self: ThermalInfo) MicError!bool { - return getBoolInt(c.mic_is_smc_boot_loader_ver_supported, self.handle); + return getBoolInt(micApi().mic_is_smc_boot_loader_ver_supported, self.handle); } pub fn smcBootLoaderVersion(self: ThermalInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_smc_boot_loader_ver, self.handle, buffer); + return getString(micApi().mic_get_smc_boot_loader_ver, self.handle, buffer); } pub fn fscStatus(self: ThermalInfo) MicError!u32 { - return getValue(u32, c.mic_get_fsc_status, self.handle); + return getValue(u32, micApi().mic_get_fsc_status, self.handle); } pub fn dieTemp(self: ThermalInfo) MicError!u32 { - return getValue(u32, c.mic_get_die_temp, self.handle); + return getValue(u32, micApi().mic_get_die_temp, self.handle); } pub fn isDieTempValid(self: ThermalInfo) MicError!bool { - return getBoolInt(c.mic_is_die_temp_valid, self.handle); + return getBoolInt(micApi().mic_is_die_temp_valid, self.handle); } pub fn gddrTemp(self: ThermalInfo) MicError!u16 { - return getValue(u16, c.mic_get_gddr_temp, self.handle); + return getValue(u16, micApi().mic_get_gddr_temp, self.handle); } pub fn isGddrTempValid(self: ThermalInfo) MicError!bool { - return getBoolInt(c.mic_is_gddr_temp_valid, self.handle); + return getBoolInt(micApi().mic_is_gddr_temp_valid, self.handle); } pub fn fanInTemp(self: ThermalInfo) MicError!u16 { - return getValue(u16, c.mic_get_fanin_temp, self.handle); + return getValue(u16, micApi().mic_get_fanin_temp, self.handle); } pub fn isFanInTempValid(self: ThermalInfo) MicError!bool { - return getBoolInt(c.mic_is_fanin_temp_valid, self.handle); + return getBoolInt(micApi().mic_is_fanin_temp_valid, self.handle); } pub fn fanOutTemp(self: ThermalInfo) MicError!u16 { - return getValue(u16, c.mic_get_fanout_temp, self.handle); + return getValue(u16, micApi().mic_get_fanout_temp, self.handle); } pub fn isFanOutTempValid(self: ThermalInfo) MicError!bool { - return getBoolInt(c.mic_is_fanout_temp_valid, self.handle); + return getBoolInt(micApi().mic_is_fanout_temp_valid, self.handle); } pub fn vccpTemp(self: ThermalInfo) MicError!u16 { - return getValue(u16, c.mic_get_vccp_temp, self.handle); + return getValue(u16, micApi().mic_get_vccp_temp, self.handle); } pub fn isVccpTempValid(self: ThermalInfo) MicError!bool { - return getBoolInt(c.mic_is_vccp_temp_valid, self.handle); + return getBoolInt(micApi().mic_is_vccp_temp_valid, self.handle); } pub fn vddgTemp(self: ThermalInfo) MicError!u16 { - return getValue(u16, c.mic_get_vddg_temp, self.handle); + return getValue(u16, micApi().mic_get_vddg_temp, self.handle); } pub fn isVddgTempValid(self: ThermalInfo) MicError!bool { - return getBoolInt(c.mic_is_vddg_temp_valid, self.handle); + return getBoolInt(micApi().mic_is_vddg_temp_valid, self.handle); } pub fn vddqTemp(self: ThermalInfo) MicError!u16 { - return getValue(u16, c.mic_get_vddq_temp, self.handle); + return getValue(u16, micApi().mic_get_vddq_temp, self.handle); } pub fn isVddqTempValid(self: ThermalInfo) MicError!bool { - return getBoolInt(c.mic_is_vddq_temp_valid, self.handle); + return getBoolInt(micApi().mic_is_vddq_temp_valid, self.handle); } pub fn fanRpm(self: ThermalInfo) MicError!u32 { - return getValue(u32, c.mic_get_fan_rpm, self.handle); + return getValue(u32, micApi().mic_get_fan_rpm, self.handle); } pub fn fanPwm(self: ThermalInfo) MicError!u32 { - return getValue(u32, c.mic_get_fan_pwm, self.handle); + return getValue(u32, micApi().mic_get_fan_pwm, self.handle); } }; @@ -569,48 +1035,48 @@ pub const MemoryInfo = struct { pub fn init(device: Device) MicError!MemoryInfo { var handle: ?*c.struct_mic_device_mem = null; - try check(c.mic_get_memory_info(device.handle, &handle)); + try check(micApi().mic_get_memory_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_device_mem, handle) }; } pub fn deinit(self: *MemoryInfo) void { - _ = c.mic_free_memory_info(self.handle); + _ = micApi().mic_free_memory_info(self.handle); } pub fn vendor(self: MemoryInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_memory_vendor, self.handle, buffer); + return getString(micApi().mic_get_memory_vendor, self.handle, buffer); } pub fn revision(self: MemoryInfo) MicError!u32 { - return getValue(u32, c.mic_get_memory_revision, self.handle); + return getValue(u32, micApi().mic_get_memory_revision, self.handle); } pub fn density(self: MemoryInfo) MicError!u32 { - return getValue(u32, c.mic_get_memory_density, self.handle); + return getValue(u32, micApi().mic_get_memory_density, self.handle); } pub fn size(self: MemoryInfo) MicError!u32 { - return getValue(u32, c.mic_get_memory_size, self.handle); + return getValue(u32, micApi().mic_get_memory_size, self.handle); } pub fn speed(self: MemoryInfo) MicError!u32 { - return getValue(u32, c.mic_get_memory_speed, self.handle); + return getValue(u32, micApi().mic_get_memory_speed, self.handle); } pub fn memoryType(self: MemoryInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_memory_type, self.handle, buffer); + return getString(micApi().mic_get_memory_type, self.handle, buffer); } pub fn frequency(self: MemoryInfo) MicError!u32 { - return getValue(u32, c.mic_get_memory_frequency, self.handle); + return getValue(u32, micApi().mic_get_memory_frequency, self.handle); } pub fn voltage(self: MemoryInfo) MicError!u32 { - return getValue(u32, c.mic_get_memory_voltage, self.handle); + return getValue(u32, micApi().mic_get_memory_voltage, self.handle); } pub fn eccMode(self: MemoryInfo) MicError!u16 { - return getValue(u16, c.mic_get_ecc_mode, self.handle); + return getValue(u16, micApi().mic_get_ecc_mode, self.handle); } }; @@ -629,36 +1095,36 @@ pub const ProcessorInfo = struct { pub fn init(device: Device) MicError!ProcessorInfo { var handle: ?*c.struct_mic_processor_info = null; - try check(c.mic_get_processor_info(device.handle, &handle)); + try check(micApi().mic_get_processor_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_processor_info, handle) }; } pub fn deinit(self: *ProcessorInfo) void { - _ = c.mic_free_processor_info(self.handle); + _ = micApi().mic_free_processor_info(self.handle); } pub fn model(self: ProcessorInfo) MicError!ProcessorModel { var value: ProcessorModel = .{ .model = 0, .model_ext = 0 }; - try check(c.mic_get_processor_model(self.handle, &value.model, &value.model_ext)); + try check(micApi().mic_get_processor_model(self.handle, &value.model, &value.model_ext)); return value; } pub fn family(self: ProcessorInfo) MicError!ProcessorFamily { var value: ProcessorFamily = .{ .family = 0, .family_ext = 0 }; - try check(c.mic_get_processor_family(self.handle, &value.family, &value.family_ext)); + try check(micApi().mic_get_processor_family(self.handle, &value.family, &value.family_ext)); return value; } pub fn processorType(self: ProcessorInfo) MicError!u16 { - return getValue(u16, c.mic_get_processor_type, self.handle); + return getValue(u16, micApi().mic_get_processor_type, self.handle); } pub fn steppingId(self: ProcessorInfo) MicError!u32 { - return getValue(u32, c.mic_get_processor_steppingid, self.handle); + return getValue(u32, micApi().mic_get_processor_steppingid, self.handle); } pub fn stepping(self: ProcessorInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_processor_stepping, self.handle, buffer); + return getString(micApi().mic_get_processor_stepping, self.handle, buffer); } }; @@ -667,24 +1133,24 @@ pub const CoresInfo = struct { pub fn init(device: Device) MicError!CoresInfo { var handle: ?*c.struct_mic_cores_info = null; - try check(c.mic_get_cores_info(device.handle, &handle)); + try check(micApi().mic_get_cores_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_cores_info, handle) }; } pub fn deinit(self: *CoresInfo) void { - _ = c.mic_free_cores_info(self.handle); + _ = micApi().mic_free_cores_info(self.handle); } pub fn count(self: CoresInfo) MicError!u32 { - return getValue(u32, c.mic_get_cores_count, self.handle); + return getValue(u32, micApi().mic_get_cores_count, self.handle); } pub fn voltage(self: CoresInfo) MicError!u32 { - return getValue(u32, c.mic_get_cores_voltage, self.handle); + return getValue(u32, micApi().mic_get_cores_voltage, self.handle); } pub fn frequency(self: CoresInfo) MicError!u32 { - return getValue(u32, c.mic_get_cores_frequency, self.handle); + return getValue(u32, micApi().mic_get_cores_frequency, self.handle); } }; @@ -693,24 +1159,24 @@ pub const VersionInfo = struct { pub fn init(device: Device) MicError!VersionInfo { var handle: ?*c.struct_mic_version_info = null; - try check(c.mic_get_version_info(device.handle, &handle)); + try check(micApi().mic_get_version_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_version_info, handle) }; } pub fn deinit(self: *VersionInfo) void { - _ = c.mic_free_version_info(self.handle); + _ = micApi().mic_free_version_info(self.handle); } pub fn uosVersion(self: VersionInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_uos_version, self.handle, buffer); + return getString(micApi().mic_get_uos_version, self.handle, buffer); } pub fn flashVersion(self: VersionInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_flash_version, self.handle, buffer); + return getString(micApi().mic_get_flash_version, self.handle, buffer); } pub fn fscStrap(self: VersionInfo, buffer: []u8) MicError![]const u8 { - return getString(c.mic_get_fsc_strap, self.handle, buffer); + return getString(micApi().mic_get_fsc_strap, self.handle, buffer); } }; @@ -719,109 +1185,109 @@ pub const PowerUtilizationInfo = struct { pub fn init(device: Device) MicError!PowerUtilizationInfo { var handle: ?*c.struct_mic_power_util_info = null; - try check(c.mic_get_power_utilization_info(device.handle, &handle)); + try check(micApi().mic_get_power_utilization_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_power_util_info, handle) }; } pub fn deinit(self: *PowerUtilizationInfo) void { - _ = c.mic_free_power_utilization_info(self.handle); + _ = micApi().mic_free_power_utilization_info(self.handle); } pub fn totalPowerReadingsW0(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_total_power_readings_w0, self.handle); + return getValue(u32, micApi().mic_get_total_power_readings_w0, self.handle); } pub fn totalPowerSensorStatusW0(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_total_power_sensor_sts_w0, self.handle); + return getValue(u32, micApi().mic_get_total_power_sensor_sts_w0, self.handle); } pub fn totalPowerReadingsW1(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_total_power_readings_w1, self.handle); + return getValue(u32, micApi().mic_get_total_power_readings_w1, self.handle); } pub fn totalPowerSensorStatusW1(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_total_power_sensor_sts_w1, self.handle); + return getValue(u32, micApi().mic_get_total_power_sensor_sts_w1, self.handle); } pub fn instantaneousPowerReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_inst_power_readings, self.handle); + return getValue(u32, micApi().mic_get_inst_power_readings, self.handle); } pub fn instantaneousPowerSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_inst_power_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_inst_power_sensor_sts, self.handle); } pub fn maxInstantaneousPowerReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_max_inst_power_readings, self.handle); + return getValue(u32, micApi().mic_get_max_inst_power_readings, self.handle); } pub fn maxInstantaneousPowerSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_max_inst_power_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_max_inst_power_sensor_sts, self.handle); } pub fn pciePowerReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_pcie_power_readings, self.handle); + return getValue(u32, micApi().mic_get_pcie_power_readings, self.handle); } pub fn pciePowerSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_pcie_power_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_pcie_power_sensor_sts, self.handle); } pub fn c2x3PowerReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_c2x3_power_readings, self.handle); + return getValue(u32, micApi().mic_get_c2x3_power_readings, self.handle); } pub fn c2x3PowerSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_c2x3_power_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_c2x3_power_sensor_sts, self.handle); } pub fn c2x4PowerReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_c2x4_power_readings, self.handle); + return getValue(u32, micApi().mic_get_c2x4_power_readings, self.handle); } pub fn c2x4PowerSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_c2x4_power_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_c2x4_power_sensor_sts, self.handle); } pub fn vccpPowerReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vccp_power_readings, self.handle); + return getValue(u32, micApi().mic_get_vccp_power_readings, self.handle); } pub fn vccpPowerSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vccp_power_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vccp_power_sensor_sts, self.handle); } pub fn vccpCurrentReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vccp_current_readings, self.handle); + return getValue(u32, micApi().mic_get_vccp_current_readings, self.handle); } pub fn vccpCurrentSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vccp_current_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vccp_current_sensor_sts, self.handle); } pub fn vccpVoltageReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vccp_voltage_readings, self.handle); + return getValue(u32, micApi().mic_get_vccp_voltage_readings, self.handle); } pub fn vccpVoltageSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vccp_voltage_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vccp_voltage_sensor_sts, self.handle); } pub fn vddgPowerReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddg_power_readings, self.handle); + return getValue(u32, micApi().mic_get_vddg_power_readings, self.handle); } pub fn vddgPowerSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddg_power_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vddg_power_sensor_sts, self.handle); } pub fn vddgCurrentReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddg_current_readings, self.handle); + return getValue(u32, micApi().mic_get_vddg_current_readings, self.handle); } pub fn vddgCurrentSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddg_current_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vddg_current_sensor_sts, self.handle); } pub fn vddgVoltageReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddg_voltage_readings, self.handle); + return getValue(u32, micApi().mic_get_vddg_voltage_readings, self.handle); } pub fn vddgVoltageSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddg_voltage_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vddg_voltage_sensor_sts, self.handle); } pub fn vddqPowerReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddq_power_readings, self.handle); + return getValue(u32, micApi().mic_get_vddq_power_readings, self.handle); } pub fn vddqPowerSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddq_power_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vddq_power_sensor_sts, self.handle); } pub fn vddqCurrentReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddq_current_readings, self.handle); + return getValue(u32, micApi().mic_get_vddq_current_readings, self.handle); } pub fn vddqCurrentSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddq_current_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vddq_current_sensor_sts, self.handle); } pub fn vddqVoltageReadings(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddq_voltage_readings, self.handle); + return getValue(u32, micApi().mic_get_vddq_voltage_readings, self.handle); } pub fn vddqVoltageSensorStatus(self: PowerUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_vddq_voltage_sensor_sts, self.handle); + return getValue(u32, micApi().mic_get_vddq_voltage_sensor_sts, self.handle); } }; @@ -830,28 +1296,28 @@ pub const PowerLimit = struct { pub fn init(device: Device) MicError!PowerLimit { var handle: ?*c.struct_mic_power_limit = null; - try check(c.mic_get_power_limit(device.handle, &handle)); + try check(micApi().mic_get_power_limit(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_power_limit, handle) }; } pub fn deinit(self: *PowerLimit) void { - _ = c.mic_free_power_limit(self.handle); + _ = micApi().mic_free_power_limit(self.handle); } pub fn physicalLimit(self: PowerLimit) MicError!u32 { - return getValue(u32, c.mic_get_power_phys_limit, self.handle); + return getValue(u32, micApi().mic_get_power_phys_limit, self.handle); } pub fn highWatermark(self: PowerLimit) MicError!u32 { - return getValue(u32, c.mic_get_power_hmrk, self.handle); + return getValue(u32, micApi().mic_get_power_hmrk, self.handle); } pub fn lowWatermark(self: PowerLimit) MicError!u32 { - return getValue(u32, c.mic_get_power_lmrk, self.handle); + return getValue(u32, micApi().mic_get_power_lmrk, self.handle); } pub fn timeWindow0(self: PowerLimit) MicError!u32 { - return getValue(u32, c.mic_get_time_window0, self.handle); + return getValue(u32, micApi().mic_get_time_window0, self.handle); } pub fn timeWindow1(self: PowerLimit) MicError!u32 { - return getValue(u32, c.mic_get_time_window1, self.handle); + return getValue(u32, micApi().mic_get_time_window1, self.handle); } }; @@ -860,22 +1326,22 @@ pub const MemoryUtilizationInfo = struct { pub fn init(device: Device) MicError!MemoryUtilizationInfo { var handle: ?*c.struct_mic_memory_util_info = null; - try check(c.mic_get_memory_utilization_info(device.handle, &handle)); + try check(micApi().mic_get_memory_utilization_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_memory_util_info, handle) }; } pub fn deinit(self: *MemoryUtilizationInfo) void { - _ = c.mic_free_memory_utilization_info(self.handle); + _ = micApi().mic_free_memory_utilization_info(self.handle); } pub fn totalMemorySize(self: MemoryUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_total_memory_size, self.handle); + return getValue(u32, micApi().mic_get_total_memory_size, self.handle); } pub fn availableMemorySize(self: MemoryUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_available_memory_size, self.handle); + return getValue(u32, micApi().mic_get_available_memory_size, self.handle); } pub fn memoryBuffersSize(self: MemoryUtilizationInfo) MicError!u32 { - return getValue(u32, c.mic_get_memory_buffers_size, self.handle); + return getValue(u32, micApi().mic_get_memory_buffers_size, self.handle); } }; @@ -884,61 +1350,61 @@ pub const CoreUtil = struct { pub fn init() MicError!CoreUtil { var handle: ?*c.struct_mic_core_util = null; - try check(c.mic_alloc_core_util(&handle)); + try check(micApi().mic_alloc_core_util(&handle)); return .{ .handle = try ensureHandle(c.struct_mic_core_util, handle) }; } pub fn deinit(self: *CoreUtil) void { - _ = c.mic_free_core_util(self.handle); + _ = micApi().mic_free_core_util(self.handle); } pub fn update(self: CoreUtil, device: Device) MicError!void { - try check(c.mic_update_core_util(device.handle, self.handle)); + try check(micApi().mic_update_core_util(device.handle, self.handle)); } pub fn idleCounters(self: CoreUtil, counters: []u64) MicError!void { if (counters.len == 0) return error.OutOfRange; - try check(c.mic_get_idle_counters(self.handle, counters.ptr)); + try check(micApi().mic_get_idle_counters(self.handle, counters.ptr)); } pub fn niceCounters(self: CoreUtil, counters: []u64) MicError!void { if (counters.len == 0) return error.OutOfRange; - try check(c.mic_get_nice_counters(self.handle, counters.ptr)); + try check(micApi().mic_get_nice_counters(self.handle, counters.ptr)); } pub fn systemCounters(self: CoreUtil, counters: []u64) MicError!void { if (counters.len == 0) return error.OutOfRange; - try check(c.mic_get_sys_counters(self.handle, counters.ptr)); + try check(micApi().mic_get_sys_counters(self.handle, counters.ptr)); } pub fn userCounters(self: CoreUtil, counters: []u64) MicError!void { if (counters.len == 0) return error.OutOfRange; - try check(c.mic_get_user_counters(self.handle, counters.ptr)); + try check(micApi().mic_get_user_counters(self.handle, counters.ptr)); } pub fn idleSum(self: CoreUtil) MicError!u64 { - return getValue(u64, c.mic_get_idle_sum, self.handle); + return getValue(u64, micApi().mic_get_idle_sum, self.handle); } pub fn systemSum(self: CoreUtil) MicError!u64 { - return getValue(u64, c.mic_get_sys_sum, self.handle); + return getValue(u64, micApi().mic_get_sys_sum, self.handle); } pub fn niceSum(self: CoreUtil) MicError!u64 { - return getValue(u64, c.mic_get_nice_sum, self.handle); + return getValue(u64, micApi().mic_get_nice_sum, self.handle); } pub fn userSum(self: CoreUtil) MicError!u64 { - return getValue(u64, c.mic_get_user_sum, self.handle); + return getValue(u64, micApi().mic_get_user_sum, self.handle); } pub fn jiffyCounter(self: CoreUtil) MicError!u64 { - return getValue(u64, c.mic_get_jiffy_counter, self.handle); + return getValue(u64, micApi().mic_get_jiffy_counter, self.handle); } pub fn numCores(self: CoreUtil) MicError!u16 { - return getValue(u16, c.mic_get_num_cores, self.handle); + return getValue(u16, micApi().mic_get_num_cores, self.handle); } pub fn threadsPerCore(self: CoreUtil) MicError!u16 { - return getValue(u16, c.mic_get_threads_core, self.handle); + return getValue(u16, micApi().mic_get_threads_core, self.handle); } pub fn tickCount(self: CoreUtil) MicError!u32 { - return getValue(u32, c.mic_get_tick_count, self.handle); + return getValue(u32, micApi().mic_get_tick_count, self.handle); } pub fn counterCount(self: CoreUtil) MicError!usize { @@ -951,22 +1417,22 @@ pub const TurboInfo = struct { pub fn init(device: Device) MicError!TurboInfo { var handle: ?*c.struct_mic_turbo_info = null; - try check(c.mic_get_turbo_state_info(device.handle, &handle)); + try check(micApi().mic_get_turbo_state_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_turbo_info, handle) }; } pub fn deinit(self: *TurboInfo) void { - _ = c.mic_free_turbo_info(self.handle); + _ = micApi().mic_free_turbo_info(self.handle); } pub fn state(self: TurboInfo) MicError!u32 { - return getValue(u32, c.mic_get_turbo_state, self.handle); + return getValue(u32, micApi().mic_get_turbo_state, self.handle); } pub fn mode(self: TurboInfo) MicError!u32 { - return getValue(u32, c.mic_get_turbo_mode, self.handle); + return getValue(u32, micApi().mic_get_turbo_mode, self.handle); } pub fn isStateValid(self: TurboInfo) MicError!bool { - return getBoolU32(c.mic_get_turbo_state_valid, self.handle); + return getBoolU32(micApi().mic_get_turbo_state_valid, self.handle); } }; @@ -975,37 +1441,37 @@ pub const ThrottleStateInfo = struct { pub fn init(device: Device) MicError!ThrottleStateInfo { var handle: ?*c.struct_mic_throttle_state_info = null; - try check(c.mic_get_throttle_state_info(device.handle, &handle)); + try check(micApi().mic_get_throttle_state_info(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_throttle_state_info, handle) }; } pub fn deinit(self: *ThrottleStateInfo) void { - _ = c.mic_free_throttle_state_info(self.handle); + _ = micApi().mic_free_throttle_state_info(self.handle); } pub fn thermalActive(self: ThrottleStateInfo) MicError!bool { - return getBoolInt(c.mic_get_thermal_ttl_active, self.handle); + return getBoolInt(micApi().mic_get_thermal_ttl_active, self.handle); } pub fn thermalCurrentLength(self: ThrottleStateInfo) MicError!u32 { - return getValue(u32, c.mic_get_thermal_ttl_current_len, self.handle); + return getValue(u32, micApi().mic_get_thermal_ttl_current_len, self.handle); } pub fn thermalCount(self: ThrottleStateInfo) MicError!u32 { - return getValue(u32, c.mic_get_thermal_ttl_count, self.handle); + return getValue(u32, micApi().mic_get_thermal_ttl_count, self.handle); } pub fn thermalTime(self: ThrottleStateInfo) MicError!u32 { - return getValue(u32, c.mic_get_thermal_ttl_time, self.handle); + return getValue(u32, micApi().mic_get_thermal_ttl_time, self.handle); } pub fn powerActive(self: ThrottleStateInfo) MicError!bool { - return getBoolInt(c.mic_get_power_ttl_active, self.handle); + return getBoolInt(micApi().mic_get_power_ttl_active, self.handle); } pub fn powerCurrentLength(self: ThrottleStateInfo) MicError!u32 { - return getValue(u32, c.mic_get_power_ttl_current_len, self.handle); + return getValue(u32, micApi().mic_get_power_ttl_current_len, self.handle); } pub fn powerCount(self: ThrottleStateInfo) MicError!u32 { - return getValue(u32, c.mic_get_power_ttl_count, self.handle); + return getValue(u32, micApi().mic_get_power_ttl_count, self.handle); } pub fn powerTime(self: ThrottleStateInfo) MicError!u32 { - return getValue(u32, c.mic_get_power_ttl_time, self.handle); + return getValue(u32, micApi().mic_get_power_ttl_time, self.handle); } }; @@ -1014,25 +1480,25 @@ pub const UosPmConfig = struct { pub fn init(device: Device) MicError!UosPmConfig { var handle: ?*c.struct_mic_uos_pm_config = null; - try check(c.mic_get_uos_pm_config(device.handle, &handle)); + try check(micApi().mic_get_uos_pm_config(device.handle, &handle)); return .{ .handle = try ensureHandle(c.struct_mic_uos_pm_config, handle) }; } pub fn deinit(self: *UosPmConfig) void { - _ = c.mic_free_uos_pm_config(self.handle); + _ = micApi().mic_free_uos_pm_config(self.handle); } pub fn cpuFreqMode(self: UosPmConfig) MicError!c_int { - return getValue(c_int, c.mic_get_cpufreq_mode, self.handle); + return getValue(c_int, micApi().mic_get_cpufreq_mode, self.handle); } pub fn coreC6Mode(self: UosPmConfig) MicError!c_int { - return getValue(c_int, c.mic_get_corec6_mode, self.handle); + return getValue(c_int, micApi().mic_get_corec6_mode, self.handle); } pub fn pc3Mode(self: UosPmConfig) MicError!c_int { - return getValue(c_int, c.mic_get_pc3_mode, self.handle); + return getValue(c_int, micApi().mic_get_pc3_mode, self.handle); } pub fn pc6Mode(self: UosPmConfig) MicError!c_int { - return getValue(c_int, c.mic_get_pc6_mode, self.handle); + return getValue(c_int, micApi().mic_get_pc6_mode, self.handle); } }; diff --git a/third_party/NOTICES.md b/third_party/NOTICES.md deleted file mode 100644 index 7e06cd4..0000000 --- a/third_party/NOTICES.md +++ /dev/null @@ -1,7 +0,0 @@ -# Third-party notices - -This package is a Zig wrapper only. It does not vendor or redistribute Intel/CIRCL `miclib.h`, `scif.h`, `libmicmgmt`, `libscif`, MPSS, or any Xeon Phi firmware/tooling. - -The upstream `CIRCL/miclib` repository describes itself as `miclib v3.6.1 (Intel Xeon Phi Coprocessor) for Ubuntu LTS 14.04 Trusty (extracted from mpss-micmgmt)`. - -The upstream `miclib.h` header is licensed under LGPL-2.1 text in its header comments and carries Intel notices. Link and distribute the native library according to the license terms that apply to your installed MPSS/miclib build. diff --git a/third_party/miclib.h b/third_party/miclib.h new file mode 100644 index 0000000..c15c203 --- /dev/null +++ b/third_party/miclib.h @@ -0,0 +1,458 @@ +/* + * Copyright 2010-2013 Intel Corporation. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 2.1. + * + * This library 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 + * Lesser General Public License for more details. + * + * Disclaimer: The codes contained in these modules may be specific + * to the Intel Software Development Platform codenamed Knights Ferry, + * and the Intel product codenamed Knights Corner, and are not backward + * compatible with other Intel products. Additionally, Intel will NOT + * support the codes or instruction set in future products. + * + * Intel offers no warranty of any kind regarding the code. This code is + * licensed on an "AS IS" basis and Intel is not obligated to provide + * any support, assistance, installation, training, or other services + * of any kind. Intel is also not obligated to provide any updates, + * enhancements or extensions. Intel specifically disclaims any warranty + * of merchantability, non-infringement, fitness for any particular + * purpose, and any other warranty. + * + * Further, Intel disclaims all liability of any kind, including but + * not limited to liability for infringement of any proprietary rights, + * relating to the use of the code, even if Intel is notified of the + * possibility of such liability. Except as expressly stated in an Intel + * license agreement provided with this code and agreed upon with Intel, + * no license, express or implied, by estoppel or otherwise, to any + * intellectual property rights is granted herein. + */ + +#ifndef MICLIB_INCLUDE_MICLIB_H_ +#define MICLIB_INCLUDE_MICLIB_H_ + +#include +#include +#include +#include +#include +#include "scif.h" + +/* if in linux or static library in windows */ +#ifdef WIN32 +#define NAME_MAX (1000) +#endif + +#ifdef __cplusplus +extern "C" { +#endif +struct mic_device; +struct mic_devices_list; +struct mic_device_mem; +struct mic_processor_info; +struct mic_thermal_info; +struct mic_version_info; +struct mic_cores_info; +struct mic_power_util_info; +struct mic_memory_util_info; +struct mic_core_util; +struct mic_power_limit; +struct mic_pci_config; +struct mic_flash_op; +struct mic_flash_status_info; +struct mic_turbo_info; +struct mic_throttle_state_info; +struct mic_uos_pm_config; +#ifdef __cplusplus +} +#endif + +/* Values returned in mic_get_device_type() */ +#define KNC_ID (1) + +/* + * The following are the error codes returned by the API + */ +typedef enum _error_code { + E_MIC_SUCCESS = 0, + E_MIC_INVAL = 1, + E_MIC_ACCESS, + E_MIC_NOENT, + E_MIC_UNSUPPORTED_DEV, + E_MIC_NOT_IMPLEMENTED, + E_MIC_DRIVER_INIT, + E_MIC_DRIVER_NOT_LOADED, + E_MIC_IOCTL_FAILED, + E_MIC_ERROR_NOT_FOUND, + E_MIC_NOMEM, + E_MIC_RANGE, + E_MIC_INTERNAL, + E_MIC_SYSTEM, + E_MIC_SCIF_ERROR, + E_MIC_RAS_ERROR, + E_MIC_STACK, + E_MIC_GET_WMI_PARAM_VALUE_FAILED, + E_NO_WINDOWS_SUPPORT, + E_WMI_FAILED +} mic_error_code; + +#define FLASH_OP_STATUS (0x1 << 4) +#define SMC_OP_STATUS (0x2 << 4) +typedef enum _flash_status { + FLASH_OP_IDLE = 0, + FLASH_OP_INVALID, + FLASH_OP_IN_PROGRESS = (FLASH_OP_STATUS | 1), + FLASH_OP_COMPLETED, + FLASH_OP_FAILED, + FLASH_OP_AUTH_FAILED, + SMC_OP_IN_PROGRESS = (SMC_OP_STATUS | 1), + SMC_OP_COMPLETED, + SMC_OP_FAILED, + SMC_OP_AUTH_FAILED +} mic_flash_status; + +#define FLASH_OP(status) ((status) & FLASH_OP_STATUS) +#define SMC_OP(status) ((status) & SMC_OP_STATUS) + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error handling */ +const char *mic_get_error_string(); +int mic_clear_error_string(); +int mic_get_ras_errno(); +const char *mic_get_ras_error_string(int ras_errno); + +/* Device mode switch/start/stop */ +int mic_enter_maint_mode(struct mic_device *mdh); +int mic_leave_maint_mode(struct mic_device *mdh); +int mic_in_maint_mode(struct mic_device *mdh, int *mode); +int mic_in_ready_state(struct mic_device *mdh, int *state); + +/* Initalization, general access to device */ +int mic_get_devices(struct mic_devices_list **devices); +int mic_free_devices(struct mic_devices_list *devices); +int mic_get_ndevices(struct mic_devices_list *devices, int *ndevices); +int mic_get_device_at_index(struct mic_devices_list *devices, int + index, int *device); +int mic_open_device(struct mic_device **device, uint32_t + device_num); +int mic_close_device(struct mic_device *device); + +/* General device information */ +int mic_get_post_code(struct mic_device *mdh, char *postcode, size_t *bufsize); +int mic_get_device_type(struct mic_device *device, uint32_t *device_type); +const char *mic_get_device_name(struct mic_device *device); +int mic_get_silicon_sku(struct mic_device *mdh, char *sku, size_t *size); +int mic_get_serial_number(struct mic_device *mdh, char *serial, size_t *size); +int mic_get_uuid(struct mic_device *mdh, uint8_t *uuid, size_t *size); +int mic_get_sysfs_attribute(struct mic_device *mdh, const + char *entry, char *value, size_t *size); +int mic_is_ras_avail(struct mic_device *mdh, int *ras_avail); + +/* Flash operations requiring maint mode */ +int mic_flash_update_start(struct mic_device *mdh, void *buf, size_t + bufsize, struct mic_flash_op **desc); +int mic_flash_update_done(struct mic_flash_op *desc); +int mic_flash_read_start(struct mic_device *mdh, void *buf, size_t + bufsize, struct mic_flash_op **desc); +int mic_flash_read_done(struct mic_flash_op *desc); +int mic_set_ecc_mode_start(struct mic_device *mdh, uint16_t + ecc_enabled, struct mic_flash_op **desc); +int mic_set_ecc_mode_done(struct mic_flash_op *desc); +int mic_get_flash_status_info(struct mic_flash_op *desc, struct + mic_flash_status_info **status); +int mic_get_progress(struct mic_flash_status_info *status, uint32_t *percent); +int mic_get_status(struct mic_flash_status_info *status, int *cmd_status); +int mic_get_ext_status(struct mic_flash_status_info *status, int *ext_status); +int mic_free_flash_status_info(struct + mic_flash_status_info *status); +int mic_get_flash_vendor_device(struct mic_device *mdh, char *buf, + size_t *size); + +/* Flash operations not requiring maint mode */ +int mic_flash_size(struct mic_device *mdh, size_t *size); +int mic_flash_active_offs(struct mic_device *mdh, off_t *active); +int mic_flash_version(struct mic_device *mdh, void *buf, char *str, size_t + size); + +/* Pci configuration */ +int mic_get_pci_config(struct mic_device *mdh, struct + mic_pci_config **conf); +int mic_get_pci_domain_id(struct mic_pci_config *conf, uint16_t *domain); +int mic_get_bus_number(struct mic_pci_config *conf, uint16_t *bus_no); +int mic_get_device_number(struct mic_pci_config *conf, uint16_t *dev_no); +int mic_get_vendor_id(struct mic_pci_config *conf, uint16_t *id); +int mic_get_device_id(struct mic_pci_config *conf, uint16_t *id); +int mic_get_revision_id(struct mic_pci_config *conf, uint8_t *id); +int mic_get_subsystem_id(struct mic_pci_config *conf, uint16_t *id); +int mic_get_link_speed(struct mic_pci_config *conf, char *speed, size_t *size); +int mic_get_link_width(struct mic_pci_config *conf, uint32_t *width); +int mic_get_max_payload(struct mic_pci_config *conf, uint32_t *payload); +int mic_get_max_readreq(struct mic_pci_config *conf, uint32_t *readreq); +int mic_get_pci_class_code(struct mic_pci_config *conf, char *class_code, + size_t *size); +int mic_free_pci_config(struct mic_pci_config *conf); + +/* Thermal info */ +int mic_get_thermal_info(struct mic_device *mdh, struct + mic_thermal_info **thermal); +int mic_get_smc_hwrevision(struct mic_thermal_info *thermal, char *rev, + size_t *size); +int mic_get_smc_fwversion(struct mic_thermal_info *thermal, char *ver, + size_t *size); +int mic_is_smc_boot_loader_ver_supported(struct + mic_thermal_info *thermal, + int *supported); +int mic_get_smc_boot_loader_ver(struct mic_thermal_info *thermal, char *ver, + size_t *size); +int mic_get_fsc_status(struct mic_thermal_info *thermal, uint32_t *status); +int mic_get_die_temp(struct mic_thermal_info *thermal, uint32_t *temp); +int mic_is_die_temp_valid(struct mic_thermal_info *thermal, int *valid); +int mic_get_gddr_temp(struct mic_thermal_info *thermal, uint16_t *temp); +int mic_is_gddr_temp_valid(struct mic_thermal_info *thermal, int *valid); +int mic_get_fanin_temp(struct mic_thermal_info *thermal, uint16_t *temp); +int mic_is_fanin_temp_valid(struct mic_thermal_info *thermal, int *valid); +int mic_get_fanout_temp(struct mic_thermal_info *thermal, uint16_t *temp); +int mic_is_fanout_temp_valid(struct mic_thermal_info *thermal, int *valid); +int mic_get_vccp_temp(struct mic_thermal_info *thermal, uint16_t *temp); +int mic_is_vccp_temp_valid(struct mic_thermal_info *thermal, int *valid); +int mic_get_vddg_temp(struct mic_thermal_info *thermal, uint16_t *temp); +int mic_is_vddg_temp_valid(struct mic_thermal_info *thermal, int *valid); +int mic_get_vddq_temp(struct mic_thermal_info *thermal, uint16_t *temp); +int mic_is_vddq_temp_valid(struct mic_thermal_info *thermal, int *valid); +int mic_get_fan_rpm(struct mic_thermal_info *thermal, uint32_t *rpm); +int mic_get_fan_pwm(struct mic_thermal_info *thermal, uint32_t *pwm); +int mic_free_thermal_info(struct mic_thermal_info *thermal); + +/* Device memory info */ +int mic_get_memory_info(struct mic_device *mdh, struct + mic_device_mem **meminfo); +int mic_get_memory_vendor(struct mic_device_mem *mem, char *vendor, + size_t *bufsize); +int mic_get_memory_revision(struct mic_device_mem *mem, uint32_t *revision); +int mic_get_memory_density(struct mic_device_mem *mem, uint32_t *density); +int mic_get_memory_size(struct mic_device_mem *mem, uint32_t *size); +int mic_get_memory_speed(struct mic_device_mem *mem, uint32_t *speed); +int mic_get_memory_type(struct mic_device_mem *mem, char *type, + size_t *bufsize); +int mic_get_memory_frequency(struct mic_device_mem *mem, uint32_t *buf); +int mic_get_memory_voltage(struct mic_device_mem *mem, uint32_t *buf); +int mic_get_ecc_mode(struct mic_device_mem *mem, uint16_t *ecc); +int mic_free_memory_info(struct mic_device_mem *mem); + +/* Processor info */ +int mic_get_processor_info(struct mic_device *mdh, struct + mic_processor_info **processor); +int mic_get_processor_model(struct mic_processor_info *processor, + uint16_t *model, uint16_t *model_ext); +int mic_get_processor_family(struct mic_processor_info *processor, + uint16_t *family, uint16_t *family_ext); +int mic_get_processor_type(struct mic_processor_info *processor, + uint16_t *type); +int mic_get_processor_steppingid(struct + mic_processor_info *processor, uint32_t *id); +int mic_get_processor_stepping(struct mic_processor_info *processor, + char *stepping, size_t *size); +int mic_free_processor_info(struct mic_processor_info *processor); + +/* Uos core info */ +int mic_get_cores_info(struct mic_device *mdh, struct + mic_cores_info **cores); +int mic_get_cores_count(struct mic_cores_info *core, uint32_t *num_cores); +int mic_get_cores_voltage(struct mic_cores_info *core, uint32_t *voltage); +int mic_get_cores_frequency(struct mic_cores_info *core, uint32_t *frequency); +int mic_free_cores_info(struct mic_cores_info *cores); + +/* Version info*/ +int mic_get_version_info(struct mic_device *mdh, struct + mic_version_info **version); +int mic_get_uos_version(struct mic_version_info *version, char *uos, + size_t *size); +int mic_get_flash_version(struct mic_version_info *version, char *flash, + size_t *size); +int mic_get_fsc_strap(struct mic_version_info *version, char *strap, + size_t *size); +int mic_free_version_info(struct mic_version_info *version); + +/* Power utilization info */ +int mic_get_power_utilization_info(struct mic_device *mdh, + struct mic_power_util_info **power); +int mic_get_total_power_readings_w0(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_total_power_sensor_sts_w0(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_total_power_readings_w1(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_total_power_sensor_sts_w1(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_inst_power_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_inst_power_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_max_inst_power_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_max_inst_power_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_pcie_power_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_pcie_power_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_c2x3_power_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_c2x3_power_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_c2x4_power_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_c2x4_power_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vccp_power_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vccp_power_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vccp_current_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vccp_current_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vccp_voltage_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vccp_voltage_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vddg_power_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vddg_power_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vddg_current_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vddg_current_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vddg_voltage_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vddg_voltage_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vddq_power_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vddq_power_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vddq_current_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vddq_current_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_get_vddq_voltage_readings(struct mic_power_util_info *power, + uint32_t *pwr); +int mic_get_vddq_voltage_sensor_sts(struct mic_power_util_info *power, + uint32_t *sts); +int mic_free_power_utilization_info(struct mic_power_util_info *power); + +/* Power limits */ +int mic_get_power_limit(struct mic_device *mdh, struct + mic_power_limit **limit); +int mic_get_power_phys_limit(struct mic_power_limit *limit, uint32_t *phys_lim); +int mic_get_power_hmrk(struct mic_power_limit *limit, uint32_t *hmrk); +int mic_get_power_lmrk(struct mic_power_limit *limit, uint32_t *lmrk); +int mic_get_time_window0(struct mic_power_limit *limit, + uint32_t *time_window); +int mic_get_time_window1(struct mic_power_limit *limit, + uint32_t *time_window); +int mic_free_power_limit(struct mic_power_limit *limit); +int mic_set_power_limit0(struct mic_device *mdh, + uint32_t power, uint32_t time_window); +int mic_set_power_limit1(struct mic_device *mdh, + uint32_t power, uint32_t time_window); + +/* Memory utilization */ +int mic_get_memory_utilization_info(struct mic_device *mdh, struct + mic_memory_util_info **memory); +int mic_get_total_memory_size(struct mic_memory_util_info *memory, + uint32_t *total_size); +int mic_get_available_memory_size(struct + mic_memory_util_info *memory, + uint32_t *avail_size); +int mic_get_memory_buffers_size(struct mic_memory_util_info *memory, + uint32_t *bufs); +int mic_free_memory_utilization_info(struct + mic_memory_util_info *memory); + +/* Core utilization */ +int mic_alloc_core_util(struct mic_core_util **cutil); +int mic_update_core_util(struct mic_device *mdh, struct + mic_core_util *cutil); +int mic_get_idle_counters(struct mic_core_util *cutil, uint64_t *idle_counters); +int mic_get_nice_counters(struct mic_core_util *cutil, uint64_t *nice_counters); +int mic_get_sys_counters(struct mic_core_util *cutil, uint64_t *sys_counters); +int mic_get_user_counters(struct mic_core_util *cutil, uint64_t *user_counters); +int mic_get_idle_sum(struct mic_core_util *cutil, uint64_t *idle_sum); +int mic_get_sys_sum(struct mic_core_util *cutil, uint64_t *sys_sum); +int mic_get_nice_sum(struct mic_core_util *cutil, uint64_t *nice_sum); +int mic_get_user_sum(struct mic_core_util *cutil, uint64_t *user_sum); +int mic_get_jiffy_counter(struct mic_core_util *cutil, uint64_t *jiffy); +int mic_get_num_cores(struct mic_core_util *cutil, uint16_t *num_cores); +int mic_get_threads_core(struct mic_core_util *cutil, uint16_t *threads_core); +int mic_get_tick_count(struct mic_core_util *cutil, uint32_t *tick_count); +int mic_free_core_util(struct mic_core_util *cutil); + +/* Led mode */ +int mic_get_led_alert(struct mic_device *mdh, uint32_t *led_alert); +int mic_set_led_alert(struct mic_device *mdh, uint32_t *led_alert); + +/* Turbo info */ +int mic_get_turbo_state_info(struct mic_device *mdh, struct + mic_turbo_info **turbo); +int mic_get_turbo_state(struct mic_turbo_info *turbo, uint32_t *state); +int mic_get_turbo_mode(struct mic_turbo_info *turbo, uint32_t *mode); +int mic_get_turbo_state_valid(struct mic_turbo_info *turbo, uint32_t *valid); +int mic_set_turbo_mode(struct mic_device *mdh, uint32_t *mode); +int mic_free_turbo_info(struct mic_turbo_info *turbo); + +/* Throttle state info */ +int mic_get_throttle_state_info(struct mic_device *mdh, struct + mic_throttle_state_info **ttl_state); +int mic_get_thermal_ttl_active(struct + mic_throttle_state_info *ttl_state, int *active); +int mic_get_thermal_ttl_current_len(struct + mic_throttle_state_info * + ttl_state, uint32_t *current); +int mic_get_thermal_ttl_count(struct + mic_throttle_state_info *ttl_state, + uint32_t *count); +int mic_get_thermal_ttl_time(struct + mic_throttle_state_info *ttl_state, + uint32_t *time); +int mic_get_power_ttl_active(struct + mic_throttle_state_info *ttl_state, int *active); +int mic_get_power_ttl_current_len(struct + mic_throttle_state_info *ttl_state, + uint32_t *current); +int mic_get_power_ttl_count(struct + mic_throttle_state_info *ttl_state, + uint32_t *count); +int mic_get_power_ttl_time(struct + mic_throttle_state_info *ttl_state, uint32_t *time); +int mic_free_throttle_state_info(struct + mic_throttle_state_info *ttl_state); + +/* Uos power management config */ +int mic_get_uos_pm_config(struct mic_device *mdh, struct + mic_uos_pm_config **pm_config); +int mic_get_cpufreq_mode(struct mic_uos_pm_config *pm_config, int *mode); +int mic_get_corec6_mode(struct mic_uos_pm_config *pm_config, int *mode); +int mic_get_pc3_mode(struct mic_uos_pm_config *pm_config, int *mode); +int mic_get_pc6_mode(struct mic_uos_pm_config *pm_config, int *mode); +int mic_free_uos_pm_config(struct mic_uos_pm_config *pm_config); + +/* Smc config */ +int mic_get_smc_persistence_flag(struct mic_device *mdh, + int *persist_flag); +int mic_set_smc_persistence_flag(struct mic_device *mdh, + int persist_flag); + +#ifdef __cplusplus +} +#endif +#endif /* MICLIB_INCLUDE_MICLIB_H_ */ diff --git a/third_party/scif.h b/third_party/scif.h new file mode 100644 index 0000000..16646f4 --- /dev/null +++ b/third_party/scif.h @@ -0,0 +1,1557 @@ +/* + * Copyright 2010-2013 Intel Corporation. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, version 2.1. + * + * This library 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 + * Lesser General Public License for more details. + * + * Disclaimer: The codes contained in these modules may be specific + * to the Intel Software Development Platform codenamed Knights Ferry, + * and the Intel product codenamed Knights Corner, and are not backward + * compatible with other Intel products. Additionally, Intel will NOT + * support the codes or instruction set in future products. + * + * Intel offers no warranty of any kind regarding the code. This code is + * licensed on an "AS IS" basis and Intel is not obligated to provide + * any support, assistance, installation, training, or other services + * of any kind. Intel is also not obligated to provide any updates, + * enhancements or extensions. Intel specifically disclaims any warranty + * of merchantability, non-infringement, fitness for any particular + * purpose, and any other warranty. + * + * Further, Intel disclaims all liability of any kind, including but + * not limited to liability for infringement of any proprietary rights, + * relating to the use of the code, even if Intel is notified of the + * possibility of such liability. Except as expressly stated in an Intel + * license agreement provided with this code and agreed upon with Intel, + * no license, express or implied, by estoppel or otherwise, to any + * intellectual property rights is granted herein. + */ + +/* + * Revised 15:05 11/24/2010 + * Derived from SCIF SAS v0.41 with additional corrections + */ + +#ifndef __SCIF_H__ +#define __SCIF_H__ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SCIF_ACCEPT_SYNC 1 +#define SCIF_SEND_BLOCK 1 +#define SCIF_RECV_BLOCK 1 + +/* Start: Deprecated Temporary definition for compatability */ +#define ACCEPT_SYNC SCIF_ACCEPT_SYNC +#define SEND_BLOCK SCIF_SEND_BLOCK +#define RECV_BLOCK SCIF_RECV_BLOCK +/* End: Deprecated Temporary definition for compatability */ + +enum { + SCIF_PROT_READ = (1<<0), + SCIF_PROT_WRITE = (1<<1) +}; + +enum { + SCIF_MAP_FIXED = 0x10, + SCIF_MAP_KERNEL = 0x20 +}; + +enum { + SCIF_FENCE_INIT_SELF = (1<<0), + SCIF_FENCE_INIT_PEER = (1<<1) +}; + +enum { + SCIF_FENCE_RAS_SELF = (1<<2), + SCIF_FENCE_RAS_PEER = (1<<3) +}; + +enum { + SCIF_SIGNAL_LOCAL = (1<<4), + SCIF_SIGNAL_REMOTE = (1<<5) +}; + +#define SCIF_RMA_USECPU 1 +#define SCIF_RMA_USECACHE (1<<1) +#define SCIF_RMA_SYNC (1<<2) +#define SCIF_RMA_ORDERED (1<<3) +//! @cond (Prevent doxygen from including these) +#define SCIF_POLLIN POLLIN +#define SCIF_POLLOUT POLLOUT +#define SCIF_POLLERR POLLERR +#define SCIF_POLLHUP POLLHUP +#define SCIF_POLLNVAL POLLNVAL + +/* SCIF Reserved Ports */ +/* COI */ +#define SCIF_COI_PORT_0 40 +#define SCIF_COI_PORT_1 41 +#define SCIF_COI_PORT_2 42 +#define SCIF_COI_PORT_3 43 +#define SCIF_COI_PORT_4 44 +#define SCIF_COI_PORT_5 45 +#define SCIF_COI_PORT_6 46 +#define SCIF_COI_PORT_7 47 +#define SCIF_COI_PORT_8 48 +#define SCIF_COI_PORT_9 49 + +/* OFED */ +#define SCIF_OFED_PORT_0 60 +#define SCIF_OFED_PORT_1 61 +#define SCIF_OFED_PORT_2 62 +#define SCIF_OFED_PORT_3 63 +#define SCIF_OFED_PORT_4 64 +#define SCIF_OFED_PORT_5 65 +#define SCIF_OFED_PORT_6 66 +#define SCIF_OFED_PORT_7 67 +#define SCIF_OFED_PORT_8 68 +#define SCIF_OFED_PORT_9 69 + +/* NETDEV */ +#define SCIF_NETDEV_PORT_0 80 +#define SCIF_NETDEV_PORT_1 81 +#define SCIF_NETDEV_PORT_2 82 +#define SCIF_NETDEV_PORT_3 83 +#define SCIF_NETDEV_PORT_4 84 +#define SCIF_NETDEV_PORT_5 85 +#define SCIF_NETDEV_PORT_6 86 +#define SCIF_NETDEV_PORT_7 87 +#define SCIF_NETDEV_PORT_8 88 +#define SCIF_NETDEV_PORT_9 89 + +/* RAS */ +#define SCIF_RAS_PORT_0 100 +#define SCIF_RAS_PORT_1 101 +#define SCIF_RAS_PORT_2 102 +#define SCIF_RAS_PORT_3 103 +#define SCIF_RAS_PORT_4 104 +#define SCIF_RAS_PORT_5 105 +#define SCIF_RAS_PORT_6 106 +#define SCIF_RAS_PORT_7 107 +#define SCIF_RAS_PORT_8 108 +#define SCIF_RAS_PORT_9 109 + +/* Power Management */ +#define SCIF_PM_PORT_0 120 +#define SCIF_PM_PORT_1 121 +#define SCIF_PM_PORT_2 122 +#define SCIF_PM_PORT_3 123 +#define SCIF_PM_PORT_4 124 +#define SCIF_PM_PORT_5 125 +#define SCIF_PM_PORT_6 126 +#define SCIF_PM_PORT_7 127 +#define SCIF_PM_PORT_8 128 +#define SCIF_PM_PORT_9 129 + +/* Board Tools */ +#define SCIF_BT_PORT_0 130 +#define SCIF_BT_PORT_1 131 +#define SCIF_BT_PORT_2 132 +#define SCIF_BT_PORT_3 133 +#define SCIF_BT_PORT_4 134 +#define SCIF_BT_PORT_5 135 +#define SCIF_BT_PORT_6 136 +#define SCIF_BT_PORT_7 137 +#define SCIF_BT_PORT_8 138 +#define SCIF_BT_PORT_9 139 + +/* MIC Boot/Configuration support */ +#define MPSSD_MONRECV 160 +#define MIC_NOTIFY 161 +#define MPSSD_CRED 162 +#define MPSSD_MONSEND 163 +#define MPSSD_MICCTRL 164 +#define MPSSD_RESV5 165 +#define MPSSD_RESV6 166 +#define MPSSD_RESV7 167 +#define MPSSD_RESV8 168 +#define MPSSD_RESV9 169 + +#define SCIF_ADMIN_PORT_END 1024 + +/* MYO */ +#define SCIF_MYO_PORT_0 1025 +#define SCIF_MYO_PORT_1 1026 +#define SCIF_MYO_PORT_2 1027 +#define SCIF_MYO_PORT_3 1028 +#define SCIF_MYO_PORT_4 1029 +#define SCIF_MYO_PORT_5 1030 +#define SCIF_MYO_PORT_6 1031 +#define SCIF_MYO_PORT_7 1032 +#define SCIF_MYO_PORT_8 1033 +#define SCIF_MYO_PORT_9 1034 + +/* SSG Tools */ +#define SCIF_ST_PORT_0 1044 +#define SCIF_ST_PORT_1 1045 +#define SCIF_ST_PORT_2 1046 +#define SCIF_ST_PORT_3 1047 +#define SCIF_ST_PORT_4 1048 +#define SCIF_ST_PORT_5 1049 +#define SCIF_ST_PORT_6 1050 +#define SCIF_ST_PORT_7 1051 +#define SCIF_ST_PORT_8 1052 +#define SCIF_ST_PORT_9 1053 + +/* End of SCIF Reserved Ports */ +#define SCIF_PORT_RSVD 1088 +//! @endcond + +typedef int scif_epd_t; + +struct scif_pollepd { + scif_epd_t epd; /* endpoint descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; + + +#define SCIF_OPEN_FAILED ((scif_epd_t)-1) +#define SCIF_REGISTER_FAILED ((off_t)-1) +#define SCIF_MMAP_FAILED ((void *)-1) + +struct scif_portID { + uint16_t node; /* node on which port resides */ + uint16_t port; /* Local port number */ +}; + +/* Start: Deprecated Temporary definition for compatability */ +#define portID scif_portID +typedef struct portID portID_t; +/* End: Deprecated Temporary definition for compatability */ + +/** + * scif_open - Create an endpoint + * + *\return + * The scif_open() function creates a new endpoint. + * + * Upon successful completion, scif_open() returns an endpoint descriptor to + * be used in subsequent SCIF functions calls to refer to that endpoint; + * otherwise: in user mode SCIF_OPEN_FAILED (that is ((scif_epd_t)-1)) is + * returned and errno is set to indicate the error; in kernel mode a NULL + * scif_epd_t is returned. + * + *\par Errors: + *- ENOMEM + * - Insufficient kernel memory was available. + *- ENXIO + * - Version mismatch between micscif driver and libscif. + */ +scif_epd_t scif_open(void); + +/** + * scif _bind - Bind an endpoint to a port + * \param epd endpoint descriptor + * \param pn port number + * + * scif_bind() binds endpoint epd to port pn, where pn is a port number on the + * local node. If pn is zero, a port number greater than or equal to + * SCIF_PORT_RSVD is assigned and returned. Each endpoint may be bound to + * exactly one local port. Ports less than 1024 when requested can only be bound + * by system (or root) processes or by processes executed by privileged users. + * + *\return + * Upon successful completion, scif_bind() returns the port number to which epd + * is bound; otherwise: in user mode -1 is returned and errno is set to + * indicate the error; in kernel mode the negative of one of the following + * errors is returned. + * + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - The endpoint or the port are already bound. + *- EISCONN + * - The endpoint is already connected. + *- ENOSPC + * - No port number available for assignment (when pn==0). + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- EACCES + * - The port requested is protected and the user is not the superuser. +*/ +int scif_bind(scif_epd_t epd, uint16_t pn); + +/** + * scif_listen - Listen for connections on an endpoint + * + * \param epd endpoint descriptor + * \param backlog maximum pending connection requests + * + * scif_listen() marks the endpoint epd as a listening endpoint - that is, as + * an endpoint that will be used to accept incoming connection requests. Once + * so marked, the endpoint is said to be in the listening state and may not be + * used as the endpoint of a connection. + * + * The endpoint, epd, must have been bound to a port. + * + * The backlog argument defines the maximum length to which the queue of + * pending connections for epd may grow. If a connection request arrives when + * the queue is full, the client may receive an error with an indication that + * the connection was refused. + * + *\return + * Upon successful completion, scif_listen() returns 0; otherwise: in user mode + * -1 is returned and errno is set to indicate the error; in kernel mode the + * negative of one of the following errors is returned. + * + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - The endpoint is not bound to a port + *- EISCONN + * - The endpoint is already connected or listening + *- ENOTTY + * - epd is not a valid endpoint descriptor +*/ +int scif_listen(scif_epd_t epd, int backlog); + +/** + * scif_connect - Initiate a connection on a port + * \param epd endpoint descriptor + * \param dst global id of port to which to connect + * + * The scif_connect() function requests the connection of endpoint epd to remote + * port dst. If the connection is successful, a peer endpoint, bound to dst, is + * created on node dst.node. On successful return, the connection is complete. + * + * If the endpoint epd has not already been bound to a port, scif_connect() + * will bind it to an unused local port. + * + * A connection is terminated when an endpoint of the connection is closed, + * either explicitly by scif_close(), or when a process that owns one of the + * endpoints of a connection is terminated. + * + * On Linux: + * scif_connect is non blocking if the file is set in non blocking mode using + * fcntl. The file handle passed to fcntl can be obtained using + * scif_get_fd(). + * + * The initiating thread can either check for connection status + * by calling connect in a loop while errno is set to EINPROGRESS + * or block on a poll()/select() system call with POLLOUT as the requested + * event. Once unblocked, calling connect again will return 0 + * if the connection was successful, or return -1 with errno set appropriately + * + *\return + * Upon successful completion, scif_connect() returns the port ID to which the + * endpoint, epd, is bound; otherwise: in user mode -1 is returned and errno is + * set to indicate the error; in kernel mode the negative of one of the + * following errors is returned. + * + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNREFUSED + * - The destination was not listening for connections or refused the + * connection request. + *- EINTR + * - Interrupted function + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - dst.port is not a valid port ID + *- EISCONN + * - The endpoint is already connected + *- ENOBUFS + * - No buffer space is available + *- ENODEV + * - The destination node does not exist, or + * - The node is lost. + *- ENOSPC + * - No port number available for assignment (when pn==0). + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- EOPNOTSUPP + * - The endpoint is listening and cannot be connected +*/ +int scif_connect(scif_epd_t epd, struct scif_portID *dst); + +/** + * scif_accept - Accept a connection on an endpoint + * \param epd endpoint descriptor + * \param peer global id of port to which connected + * \param newepd new connected endpoint descriptor + * \param flags flags + * + * The scif_accept() call extracts the first connection request on the queue of + * pending connections for the port on which epd is listening. scif_accept() + * creates a new endpoint, bound to the same port as epd, and allocates a new + * SCIF endpoint descriptor, returned in newepd, for the endpoint. The new + * endpoint is connected to the endpoint through which the connection was + * requested. epd is unaffected by this call, and remains in the listening + * state. + * + * On successful return, peer holds the global port identifier (node id and + * local port number) of the port which requested the connection. + * + * If the peer endpoint which requested the connection is closed, the endpoint + * returned by scif_accept() is closed. + * + * The number of connections that can (subsequently) be accepted on epd is only + * limited by system resources (memory). + * + * The flags argument is formed by OR'ing together zero or more of the + * following values: + *- SCIF_ACCEPT_SYNC: block until a connection request is presented. If + * SCIF_ACCEPT_SYNC is not in flags, and no pending + * connections are present on the queue, scif_accept()fails + * with an EAGAIN error + * + * On Linux in user mode, the select() and poll() functions can be used to + * determine when there is a connection request. On Microsoft Windows* and on + * Linux in kernel mode, the scif_poll() function may be used for this purpose. + * A readable event will be delivered when a connection is requested. + * + *\return + * Upon successful completion, scif_accept() returns 0; otherwise: in user mode + * -1 is returned and errno is set to indicate the error; in kernel mode the + * negative of one of the following errors is returned. + * + *\par Errors: + *- EAGAIN + * - SCIF_ACCEPT_SYNC is not set and no connections are present to be accepted, or + * - SCIF_ACCEPT_SYNC is not set and remote node failed to complete its + * connection request + *- EBADF + * - epd is not a valid endpoint descriptor + *- EINTR + * - Interrupted function + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - epd is not a listening endpoint + * - flags is invalid + * - peer is NULL + * - newepd is NULL + *- ENOBUFS + * - No buffer space is available + *- ENODEV + * - The requesting node is lost. + *- ENOMEM + * - Not enough space + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- ENOENT + * - Secondary part of epd registeration failed. +*/ +int scif_accept(scif_epd_t epd, struct scif_portID *peer, scif_epd_t +*newepd, int flags); + +/** + * scif_close - Close an endpoint + * \param epd endpoint descriptor + * + * scif_close() closes an endpoint and performs necessary teardown of + * facilities associated with that endpoint. + * + * If epd is a listening endpoint then it will no longer accept connection + * requests on the port to which it is bound. Any pending connection requests + * are rejected. + * + * If epd is a connected endpoint, then its peer endpoint is also closed. RMAs + * which are in-process through epd or its peer endpoint will complete before + * scif_close() returns. Registered windows of the local and peer endpoints are + * released as if scif_unregister() was called against each window. + * + * Closing an endpoint does not affect mappings to remote memory. These remain + * until explicitly removed by calling scif_munmap(). + * + * If the peer endpoint's receive queue is not empty at the time that epd is + * closed, then the peer endpoint can be passed as the endpoint parameter to + * scif_recv() until the receive queue is empty. + * + * If epd is bound to a port, then the port is returned to the pool of + * available ports. + * + * epd is freed and may no longer be accessed. + * + *\return + * Upon successful completion, scif_close() returns 0; otherwise: in user mode + * -1 is returned and errno is set to indicate the error; in kernel mode the + * negative of one of the following errors is returned. + * + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- EINVAL + * - epd is not a valid endpoint descriptor + */ +int scif_close(scif_epd_t epd); + +/** + * scif_send - Send a message + * \param epd endpoint descriptor + * \param msg message buffer address + * \param len message length + * \param flags blocking mode flags + * + * scif_send() sends data to the peer of endpoint epd. Up to len bytes of data + * are copied from memory starting at address msg. On successful execution the + * return value of scif_send() is the number of bytes that were sent, and is + * zero if no bytes were sent because len was zero. scif_send() may be called + * only when the endpoint is in a connected state. + * + * If a scif_send() call is non-blocking, then it sends only those bytes which + * can be sent without waiting, up to a maximum of len bytes. + * + * If a scif_send() call is blocking, then it normally returns after sending + * all len bytes. If a blocking call is interrupted or the connection is + * forcibly closed, the call is considered successful if some bytes were sent + * or len is zero, otherwise the call is considered unsuccessful. + * + * On Linux in user mode, the select() and poll() functions can be used to + * determine when the send queue is not full. On Microsoft Windows* and on + * Linux in kernel mode, the scif_poll() function may be used for this purpose. + * + * It is recommended that scif_send()/scif_recv() only be used for short + * control-type message communication between SCIF endpoints. The SCIF RMA + * APIs are expected to provide better performance for transfer sizes of + * 1024 bytes or longer. + * + * The flags argument is formed by ORing together zero or more of the following + * values: + *- SCIF_SEND_BLOCK: block until the entire message is sent. + * + *\return + * Upon successful completion, scif_send() returns the number of bytes sent; + * otherwise: in user mode -1 is returned and errno is set to indicate the + * error; in kernel mode the negative of one of the following errors is + * returned. + * + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EFAULT + * - An invalid address was specified for a parameter. + *- EINTR + * - epd was closed by scif_close() + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - flags is invalid + * - len is negative + *- ENODEV + * - The remote node is lost. + *- ENOMEM + * - Not enough space + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + */ +int scif_send(scif_epd_t epd, void *msg, int len, int flags); + +/** + * scif_recv - Receive a message + * \param epd endpoint descriptor + * \param msg message buffer address + * \param len message buffer length + * \param flags blocking mode flags + * + * scif_recv() receives data from the peer of endpoint epd. Up to len bytes of + * data are copied to memory starting at address msg. On successful execution + * the return value of scif_recv() is the number of bytes that were received, + * and is zero if no bytes were received because len was zero. scif_recv() may + * be called only when the endpoint is in a connected state. + * + * If a scif_recv() call is non-blocking, then it receives only those bytes + * which can be received without waiting, up to a maximum of len bytes. + * + * If a scif_recv() call is blocking, then it normally returns after receiving + * all len bytes. If a blocking call is interrupted or the connection is + * forcibly closed, the call is considered successful if some bytes were + * received or len is zero, otherwise the call is considered unsuccessful; + * subsequent calls to scif_recv() will successfully receive all data sent + * through peer endpoint interruption or the connection was forcibly closed. + * + * On Linux in user mode, the select() and poll() functions can be used to + * determine when data is available to be received. On Microsoft Windows* and + * on Linux in kernel mode, the scif_poll() function may be used for this + * purpose. + * + * It is recommended that scif_send()/scif_recv() only be used for short + * control-type message communication between SCIF endpoints. The SCIF RMA + * APIs are expected to provide better performance for transfer sizes of + * 1024 bytes or longer. + * + * The flags argument is formed by ORing together zero or more of the following + * values: + *- SCIF_RECV_BLOCK: block until the entire message is received. + * + *\return + * Upon successful completion, scif_recv() returns the number of bytes + * received; otherwise: in user mode -1 is returned and errno is set to + * indicate the error; in kernel mode the negative of one of the following + * errors is returned. + * + *\par Errors: + *- EAGAIN + * - The destination node is returning from a low power state. + *- EBADF + * - epd is not a valid endpoint descriptor . + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EFAULT + * - An invalid address was specified for a parameter. + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - flags is invalid, or + * - len is negative. + *- ENODEV + * - The remote node is lost. + *- ENOMEM + * - Not enough space. + *- ENOTCONN + * - The endpoint is not connected. + *- ENOTTY + * - epd is not a valid endpoint descriptor + */ +int scif_recv(scif_epd_t epd, void *msg, int len, int flags); + +/** + * scif_register - Mark a memory region for remote access. + * \param epd endpoint descriptor + * \param addr starting virtual address + * \param len length of range + * \param offset offset of window + * \param prot_flags read/write protection flags + * \param map_flags mapping flags + * + * The scif_register() function opens a window, a range of whole pages of the + * registered address space of the endpoint epd, starting at offset po and + * continuing for len bytes. The value of po, further described below, is a + * function of the parameters offset and len, and the value of map_flags. Each + * page of the window represents the physical memory page which backs the + * corresponding page of the range of virtual address pages starting at addr + * and continuing for len bytes. addr and len are constrained to be multiples + * of the page size. addr is interpreted as a user space address. A successful + * scif_register() call returns po as the return value. + * + * When SCIF_MAP_FIXED is set in the map_flags argument, po will be offset + * exactly, and offset is constrained to be a multiple of the page size. The + * mapping established by scif_register() will not replace any existing + * registration; an error is returned if any page within the range [offset, + * offset+len-1] intersects an existing window. + * Note: When SCIF_MAP_FIXED is set the current implementation limits + * offset to the range [0..2^62-1] and returns EADDRINUSE if the offset + * requested with SCIF_MAP_FIXED is in the range [2^62..2^63-1]. + * + * When SCIF_MAP_FIXED is not set, the implementation uses offset in an + * implementation-defined manner to arrive at po. The po value so chosen will + * be an area of the registered address space that the implementation deems + * suitable for a mapping of len bytes. An offset value of 0 is interpreted as + * granting the implementation complete freedom in selecting po, subject to + * constraints described below. A non-zero value of offset is taken to be a + * suggestion of an offset near which the mapping should be placed. When the + * implementation selects a value for po, it does not replace any extant + * window. In all cases, po will be a multiple of the page size. + * + * The physical pages which are so represented by a window are available for + * access in calls to scif_mmap(), scif_readfrom(), scif_writeto(), + * scif_vreadfrom(), and scif_vwriteto(). While a window is registered, the + * physical pages represented by the window will not be reused by the memory + * subsystem for any other purpose. Note that the same physical page may be + * represented by multiple windows. + * + * Subsequent operations which change the memory pages to which virtual + * addresses are mapped (such as mmap(), munmap(), scif_mmap() and + * scif_munmap()) have no effect on existing windows. + * + * On Linux, if the process will fork(), it is recommended that the registered + * virtual address range be marked with MADV_DONTFORK. Doing so will prevent + * problems due to copy-on-write semantics. + * + * The prot_flags argument is formed by OR'ing together one or more of the + * following values: + *- SCIF_PROT_READ: allow read operations from the window + *- SCIF_PROT_WRITE: allow write operations to the window + * + * The map_flags argument is formed by OR'ing together zero or more of + * the following values: + *- SCIF_MAP_FIXED: interpret offset exactly + * + *\return + * Upon successful completion, scif_register() returns the offset at which the + * mapping was placed (po); otherwise: in user mode SCIF_REGISTER_FAILED (that + * is (off_t *)-1) is returned and errno is set to indicate the error; in + * kernel mode the negative of one of the following errors is returned. + * + *\par Errors: + *- EADDRINUSE + * - SCIF_MAP_FIXED is set in map_flags, and pages in the range [offset, + * offset+len-1] are already registered + *- EAGAIN + * - The mapping could not be performed due to lack of resources + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EFAULT + * - Addresses in the range [addr , addr + len - 1] are invalid + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - map_flags is invalid, or + * - prot_flags is invalid, or + * - SCIF_MAP_FIXED is set in flags, and offset is not a multiple of + * the page size, or + * - addr is not a multiple of the page size, or + * - len is not a multiple of the page size, or is 0, or + * - offset is negative + *- ENODEV + * - The remote node is lost. + *- ENOMEM + * - Not enough space + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + */ +off_t scif_register(scif_epd_t epd, void *addr, size_t len, off_t offset, +int prot_flags, int map_flags); + +/** + * scif_unregister - Mark a memory region for remote access. + * \param epd endpoint descriptor + * \param offset start of range to unregister + * \param len length of range to unregister + * + * The scif_unregister() function closes those previously registered windows + * which are entirely within the range [offset,offset+len-1]. It is an error to + * specify a range which intersects only a subrange of a window. + * + * On a successful return, pages within the window may no longer be specified + * in calls to scif_mmap(), scif_readfrom(), scif_writeto(), scif_vreadfrom(), + * scif_vwriteto(), scif_get_pages, and scif_fence_signal(). The window, however, + * continues to exist until all previous references against it are removed. A + * window is referenced if there is a mapping to it created by scif_mmap(), or if + * scif_get_pages() was called against the window (and the pages have not been + * returned via scif_put_pages()). A window is also referenced while an RMA, in + * which some range of the window is a source or destination, is in progress. + * Finally a window is referenced while some offset in that window was specified + * to scif_fence_signal(), and the RMAs marked by that call to + * scif_fence_signal() have not completed. While a window is in this state, its + * registered address space pages are not available for use in a new registered + * window. + * + * When all such references to the window have been removed, its references to + * all the physical pages which it represents are removed. Similarly, the + * registered address space pages of the window become available for + * registration in a new window. + * + *\return + * Upon successful completion, scif_unregister() returns 0; otherwise: in user + * mode -1 is returned and errno is set to indicate the error; in kernel mode + * the negative of one of the following errors is returned. In the event of an + * error, no windows are unregistered. + * + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - The range [offset,offset+len-1] intersects a subrange of a window, or + * - offset is negative + *- ENODEV + * -The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- ENXIO + * - Addresses in the range [offset,offset+len-1] are invalid for the + * registered address space of epd. + */ +int scif_unregister(scif_epd_t epd, off_t offset, size_t len); + +/** + * scif_mmap - Map pages in virtual address space to a remote window + * \param addr virtual address range base address + * \param len length of range to be mapped + * \param prot_flags read/write protection flags + * \param map_flags mapping flags + * \param epd endpoint descriptor + * \param offset offset into remote registered address space + * + * The scif_mmap() function establishes a mapping between those whole pages of + * the process starting at address pa and continuing for len bytes, and those + * whole physical pages represented by pages of the registered address space of + * the peer of the endpoint epd, starting at offset and continuing for len + * bytes. The value of pa, further described below, is a function of the + * parameters addr and len, and the value of map_flags. offset and len are + * constrained to be multiples of the page size. A successful scif_mmap() call + * returns pa as its result. Due to Microsoft Windows limitation, On + * Microsoft Windows 7, len must be 4096. On Microsoft Windows 8 and later, + * len must be less than or equal to 4GB-4KB. + * + * Each of the pages in the specified range [offset,offset+len-1] must be + * within some registered window on the remote node. The range may intersect + * multiple registered windows, but only if those windows are contiguous in the + * registered address space. + * + * When SCIF_MAP_FIXED is set in the flags argument, pa shall be addr exactly, + * and addr is constrained to be a multiple of the page size. The mapping + * established by scif_mmap() will replace any existing mappings for those + * pages of the address space of the process starting at addr and continuing + * for len bytes. + * + * When SCIF_MAP_FIXED is not set, the implementation uses addr in an + * implementation-defined manner to arrive at pa. The pa so chosen will be an + * area of the address space that the implementation deems suitable for a + * mapping of len bytes. An addr value of 0 is interpreted as granting the + * implementation complete freedom in selecting pa, subject to constraints + * described below. A non-zero value of addr is taken to be a suggestion + * of a process address near which the mapping should be placed. When the + * implementation selects a value for pa, it never places a mapping at address + * 0, nor does it replace any extant mapping. In all cases, pa will be a + * multiple of the page size. + * + * On successful return, CPU accesses to addresses within the mapped virtual + * address range will read or write data at corresponding memory locations of + * the remote node. + * + * The remote physical pages of a mapping created by scif_mmap() remain + * available, and are not reused by the memory subsystem of the remote node, + * until the mapping is changed by a subsequent call to scif_mmap(), + * scif_munmap(), or standard functions such as mmap() and munmap(). + * + * Mapped regions of a process are automatically unmapped when the process is + * terminated. However, closing an endpoint does not automatically unmap any + * region. + * + * prot_flags has one or more of the following possible values: + *- SCIF_PROT_READ: allow the mapping if the referenced window has the + * SCIF_PROT_READ flag. + *- SCIF_PROT_WRITE: allow the mapping if the referenced window has the + * SCIF_PROT_WRITE flag. + * + * The map_flags argument is formed by OR'ing together zero or more of the + * following values: + *- SCIF_MAP_FIXED: interpret addr exactly + * + *\return + * Upon successful completion, scif_mmap() returns the address at which the + * mapping was placed (pa); otherwise SCIF_MMAP_FAILED (that is (void *)-1) is + * returned and errno is set to indicate the error. + *\par Errors: + *- EACCESS + * - prot flags is not compatible with registered window protection + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- ENOMEM + * - Insufficient kernel memory was available. + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - map_flags is invalid, or + * - prot_flags is invalid , or + * - SCIF_MAP_FIXED is set and addr is not a multiple of the page size, or + * - offset is not a multiple of the page size, or + * - len is not a multiple of the page size, or + * - len is not 4096 (Microsoft Windows 7), or + * - len is greater than 4GB-4KB (Microsoft Windows 8 or later) + *- ENODEV + * - The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- ENXIO + * - Addresses in the range [offset,offset+len-1] are invalid for the +registered + * address space of the peer of epd, or + * - offset is negative + */ +void *scif_mmap(void *addr, size_t len, int prot_flags, int map_flags, +scif_epd_t epd, off_t offset); + +/** + * scif_munmap - Remove the mapping to a remote window + * \param addr starting address of range to unmap + * \param len length of range to unmap + * + * scif_munmap() removes any mapping to those entire pages containing any + * portion of the address space, starting at addr and continuing for len bytes. + * Subsequent reference to those pages may result in the generation of a signal + * or error. + * + * If a page in the specified range was not mapped by scif_mmap(), the effect + * will be as if the standard mmap() function were called on that page. + * + * All mapped regions of a process are automatically unmapped when the process + * is terminated. + * + *\return + * Upon successful completion, scif_unmap() returns 0. Otherwise -1 is + * returned, and errno is set to indicate the error. + * + *\par Errors: + *- EINVAL + * - addr is not a multiple of the page size, or + * - len is not a multiple of the page size + */ +int scif_munmap(void *addr, size_t len); + +/** + * scif_readfrom - Copy from a remote address space + * \param epd endpoint descriptor + * \param loffset offset in local registered address space to + * which to copy + * \param len length of range to copy + * \param roffset offset in remote registered address space + * from which to copy + * \param rma_flags transfer mode flags + * + * scif_readfrom() copies len bytes from the remote registered address space of + * the peer of endpoint epd, starting at the offset roffset to the local + * registered address space of epd, starting at the offset loffset. + * + * Each of the specified ranges [loffset,loffset+len-1] and [roffset,roffset+ + * len-1] must be within some registered window or windows of the local and + * remote nodes respectively. A range may intersect multiple registered + * windows, but only if those windows are contiguous in the registered address + * space. + * + * If rma_flags includes SCIF_RMA_USECPU, then the data is copied using + * programmed read/writes. Otherwise the data is copied using DMA. If rma_- + * flags includes SCIF_RMA_SYNC, then scif_readfrom() will return after the + * transfer is complete. Otherwise, the transfer may be performed asynchron- + * ously. The order in which any two aynchronous RMA operations complete + * is non-deterministic. The synchronization functions, scif_fence_mark()/ + * scif_fence_wait() and scif_fence_signal(), can be used to synchronize to + * the completion of asynchronous RMA operations. + * + * The DMA transfer of individual bytes is not guaranteed to complete in + * address order. If rma_flags includes SCIF_RMA_ORDERED, then the last + * cacheline or partial cacheline of the source range will become visible on + * the destination node after all other transferred data in the source + * range has become visible on the destination node. + * + * The optimal DMA performance will likely be realized if both + * loffset and roffset are cacheline aligned (are a multiple of 64). Lower + * performance will likely be realized if loffset and roffset are not + * cacheline aligned but are separated by some multiple of 64. The lowest level + * of performance is likely if loffset and roffset are not separated by a + * multiple of 64. + * + * The rma_flags argument is formed by ORing together zero or more of the + * following values: + *- SCIF_RMA_USECPU: perform the transfer using the CPU, otherwise use the DMA + * engine. + *- SCIF_RMA_SYNC: perform the transfer synchronously, returning after the + * transfer has completed. Passing this flag might result in + * the API busy waiting and consuming CPU cycles while the DMA + * transfer is in progress. + *- SCIF_RMA_ORDERED: ensure that the last cacheline or partial cacheline of + * the source range becomes visible on the destination node + * after all other transferred data in the source range has + * become visible on the destination + * + *\return + * Upon successful completion, scif_readfrom() returns 0; otherwise: in user + * mode -1 is returned and errno is set to indicate the error; in kernel mode + * the negative of one of the following errors is returned. + * + *\par Errors + *- EACCESS + * - Attempt to write to a read-only range or read from a write-only range + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - rma_flags is invalid + *- ENODEV + * -The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- ENXIO + * - The range [loffset,loffset+len-1] is invalid for the registered address + * space of epd, or, + * - The range [roffset,roffset+len-1] is invalid for the registered address + * space of the peer of epd, or + * - loffset or roffset is negative +*/ +int scif_readfrom(scif_epd_t epd, off_t loffset, size_t len, off_t +roffset, int rma_flags); + +/** + * scif_writeto - Copy to a remote address space + * \param epd endpoint descriptor + * \param loffset offset in local registered address space + * from which to copy + * \param len length of range to copy + * \param roffset offset in remote registered address space to + * which to copy + * \param rma_flags transfer mode flags + * + * scif_writeto() copies len bytes from the local registered address space of + * epd, starting at the offset loffset to the remote registered address space + * of the peer of endpoint epd, starting at the offset roffset. + * + * Each of the specified ranges [loffset,loffset+len-1] and [roffset,roffset+ + * len-1] must be within some registered window or windows of the local and + * remote nodes respectively. A range may intersect multiple registered + * windows, but only if those windows are contiguous in the registered address + * space. + * + * If rma_flags includes SCIF_RMA_USECPU, then the data is copied using + * programmed read/writes. Otherwise the data is copied using DMA. If rma_- + * flags includes SCIF_RMA_SYNC, then scif_writeto() will return after the + * transfer is complete. Otherwise, the transfer may be performed asynchron- + * ously. The order in which any two aynchronous RMA operations complete + * is non-deterministic. The synchronization functions, scif_fence_mark()/ + * scif_fence_wait() and scif_fence_signal(), can be used to synchronize to + * the completion of asynchronous RMA operations. + * + * The DMA transfer of individual bytes is not guaranteed to complete in + * address order. If rma_flags includes SCIF_RMA_ORDERED, then the last + * cacheline or partial cacheline of the source range will become visible on + * the destination node after all other transferred data in the source + * range has become visible on the destination node. + * + * The optimal DMA performance will likely be realized if both + * loffset and roffset are cacheline aligned (are a multiple of 64). Lower + * performance will likely be realized if loffset and roffset are not cacheline + * aligned but are separated by some multiple of 64. The lowest level of + * performance is likely if loffset and roffset are not separated by a multiple + * of 64. + * + * The rma_flags argument is formed by ORing together zero or more of the + * following values: + *- SCIF_RMA_USECPU: perform the transfer using the CPU, otherwise use the DMA + * engine. + *- SCIF_RMA_SYNC: perform the transfer synchronously, returning after the + * transfer has completed. Passing this flag might result in + * the API busy waiting and consuming CPU cycles while the DMA + * transfer is in progress. + *- SCIF_RMA_ORDERED: ensure that the last cacheline or partial cacheline of + * the source range becomes visible on the destination node + * after all other transferred data in the source range has + * become visible on the destination + * + *\return + * Upon successful completion, scif_readfrom() returns 0; otherwise: in user + * mode -1 is returned and errno is set to indicate the error; in kernel mode + * the negative of one of the following errors is returned. + * + *\par Errors: + *- EACCESS + * - Attempt to write to a read-only range or read from a write-only range + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - rma_flags is invalid + *- ENODEV + * - The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- ENXIO + * - The range [loffset,loffset+len-1] is invalid for the registered address + * space of epd, or, + * - The range [roffset , roffset + len -1] is invalid for the registered + * address space of the peer of epd, or + * - loffset or roffset is negative + */ +int scif_writeto(scif_epd_t epd, off_t loffset, size_t len, off_t +roffset, int rma_flags); + +/** + * scif_vreadfrom - Copy from a remote address space + * \param epd endpoint descriptor + * \param addr address to which to copy + * \param len length of range to copy + * \param roffset offset in remote registered address space + * from which to copy + * \param rma_flags transfer mode flags + * + * scif_vreadfrom() copies len bytes from the remote registered address + * space of the peer of endpoint epd, starting at the offset roffset, to local + * memory, starting at addr. addr is interpreted as a user space address. + * + * The specified range [roffset,roffset+len-1] must be within some registered + * window or windows of the remote nodes respectively. The range may intersect + * multiple registered windows, but only if those windows are contiguous in the + * registered address space. + * + * If rma_flags includes SCIF_RMA_USECPU, then the data is copied using + * programmed read/writes. Otherwise the data is copied using DMA. If rma_- + * flags includes SCIF_RMA_SYNC, then scif_vreadfrom() will return after the + * transfer is complete. Otherwise, the transfer may be performed asynchron- + * ously. The order in which any two aynchronous RMA operations complete + * is non-deterministic. The synchronization functions, scif_fence_mark()/ + * scif_fence_wait() and scif_fence_signal(), can be used to synchronize to + * the completion of asynchronous RMA operations. + * + * The DMA transfer of individual bytes is not guaranteed to complete in + * address order. If rma_flags includes SCIF_RMA_ORDERED, then the last + * cacheline or partial cacheline of the source range will become visible on + * the destination node after all other transferred data in the source + * range has become visible on the destination node. + * + * If rma_flags includes SCIF_RMA_USECACHE, then the physical pages which back + * the specified local memory range may be remain in a pinned state even after + * the specified transfer completes. This may reduce overhead if some or all of + * the same virtual address range is referenced in a subsequent call of + * scif_vreadfrom() or scif_vwriteto(). + * + * The optimal DMA performance will likely be realized if both + * loffset and roffset are cacheline aligned (are a multiple of 64). Lower + * performance will likely be realized if loffset and roffset are not + * cacheline aligned but are separated by some multiple of 64. The lowest level + * of performance is likely if loffset and roffset are not separated by a + * multiple of 64. + * + * The rma_flags argument is formed by ORing together zero or more of the + * following values: + *- SCIF_RMA_USECPU: perform the transfer using the CPU, otherwise use the DMA + * engine. + *- SCIF_RMA_USECACHE: enable registration caching + *- SCIF_RMA_SYNC: perform the transfer synchronously, returning after the + * transfer has completed. Passing this flag might result in + * the API busy waiting and consuming CPU cycles while the DMA + * transfer is in progress. + *- SCIF_RMA_ORDERED: ensure that the last cacheline or partial cacheline of + * the source range becomes visible on the destination node + * after all other transferred data in the source range has + * become visible on the destination + * + *\return + * Upon successful completion, scif_vreadfrom() returns 0; otherwise: in user + * mode -1 is returned and errno is set to indicate the error; in kernel mode + * the negative of one of the following errors is returned. + * + *\par Errors: + *- EACCESS + * - Attempt to write to a read-only range or read from a write-only range + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EFAULT + * - Addresses in the range [addr,addr+len-1] are invalid + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - rma_flags is invalid + *- ENODEV + * - The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- ENXIO + * - Addresses in the range [roffset,roffset+len-1] are invalid for the + * registered address space of epd. + */ +int scif_vreadfrom(scif_epd_t epd, void *addr, size_t len, off_t offset, +int rma_flags); + +/** + * scif_vwriteto - Copy to a remote address space + * \param epd endpoint descriptor + * \param addr address from which to copy + * \param len length of range to copy + * \param roffset offset in remote registered address space to + * which to copy + * \param rma_flags transfer mode flags + * + * scif_vwriteto() copies len bytes from the local memory, starting at addr, to + * the remote registered address space of the peer of endpoint epd, starting at + * the offset roffset. addr is interpreted as a user space address. + * + * The specified range [roffset,roffset+len-1] must be within some registered + * window or windows of the remote nodes respectively. The range may intersect + * multiple registered windows, but only if those windows are contiguous in the + * registered address space. + * + * If rma_flags includes SCIF_RMA_USECPU, then the data is copied using + * programmed read/writes. Otherwise the data is copied using DMA. If rma_- + * flags includes SCIF_RMA_SYNC, then scif_vwriteto() will return after the + * transfer is complete. Otherwise, the transfer may be performed asynchron- + * ously. The order in which any two aynchronous RMA operations complete + * is non-deterministic. The synchronization functions, scif_fence_mark()/ + * scif_fence_wait() and scif_fence_signal(), can be used to synchronize to + * the completion of asynchronous RMA operations. + * + * The DMA transfer of individual bytes is not guaranteed to complete in + * address order. If rma_flags includes SCIF_RMA_ORDERED, then the last + * cacheline or partial cacheline of the source range will become visible on + * the destination node after all other transferred data in the source + * range has become visible on the destination node. + * + * If rma_flags includes SCIF_RMA_USECACHE, then the physical pages which back + * the specified local memory range may be remain in a pinned state even after + * the specified transfer completes. This may reduce overhead if some or all of + * the same virtual address range is referenced in a subsequent call of + * scif_vreadfrom() or scif_vwriteto(). + * + * The optimal DMA performance will likely be realized if both + * addr and offset are cacheline aligned (are a multiple of 64). Lower + * performance will likely be realized if addr and offset are not cacheline + * aligned but are separated by some multiple of 64. The lowest level of + * performance is likely if addr and offset are not separated by a multiple of + * 64. + * + * The rma_flags argument is formed by ORing together zero or more of the + * following values: + *- SCIF_RMA_USECPU: perform the transfer using the CPU, otherwise use the DMA + * engine. + *- SCIF_RMA_USECACHE: allow registration caching + *- SCIF_RMA_SYNC: perform the transfer synchronously, returning after the + * transfer has completed. Passing this flag might result in + * the API busy waiting and consuming CPU cycles while the DMA + * transfer is in progress. + *- SCIF_RMA_ORDERED: ensure that the last cacheline or partial cacheline of + * the source range becomes visible on the destination node + * after all other transferred data in the source range has + * become visible on the destination + * + *\return + * Upon successful completion, scif_vwriteto () returns 0; otherwise: in user + * mode -1 is returned and errno is set to indicate the error; in kernel mode + * the negative of one of the following errors is returned. + * + *\par Errors: + *- EACCESS + * - Attempt to write to a read-only range or read from a write-only range + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EFAULT + * - Addresses in the range [addr,addr+len-1] are invalid + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - rma_flags is invalid + *- ENODEV + * - The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- ENXIO + * - Addresses in the range [roffset,roffset+len-1] are invalid for the + * registered address space of epd. + */ +int scif_vwriteto(scif_epd_t epd, void *addr, size_t len, off_t offset, +int rma_flags); + +/** + * scif_fence_mark - Mark previously issued RMAs + * \param epd endpoint descriptor + * \param flags control flags + * \param mark marked handle returned as output. + * + * scif_fence_mark() returns after marking the current set of all uncompleted + * RMAs initiated through the endpoint epd or the current set of all + * uncompleted RMAs initiated through the peer of endpoint epd. The RMAs are + * marked with a value returned at mark. The application may subsequently call + * scif_fence_wait(), passing the value returned at mark, to await completion + * of all RMAs so marked. + * + * The flags argument has exactly one of the following values: + *- SCIF_FENCE_INIT_SELF: RMA operations initiated through endpoint + * epd are marked + *- SCIF_FENCE_INIT_PEER: RMA operations initiated through the peer + * of endpoint epd are marked + * + * \return + * Upon successful completion, scif_fence_mark() returns 0; otherwise: in user + * mode -1 is returned and errno is set to indicate the error; in kernel mode + * the negative of one of the following errors is returned. + * + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EINVAL + * - flags is invalid, or + * - epd is not a valid endpoint descriptor, or + *- ENODEV + * - The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOMEM + * - Insufficient kernel memory was available. + *- ENOTTY + * - epd is not a valid endpoint descriptor + */ +int scif_fence_mark(scif_epd_t epd, int flags, int *mark); + +/** + * scif_fence_wait - Wait for completion of marked RMAs + * + * \param epd endpoint descriptor + * \param mark mark request + * + * scif_fence_wait() returns after all RMAs marked with mark have completed. + * The value passed in mark must have been obtained in a previous call to + * scif_fence_mark(). + * + *\return + * Upon successful completion, scif_fence_wait() returns 0; otherwise: in user + * mode -1 is returned and errno is set to indicate the error; in kernel mode + * the negative of one of the following errors is returned. + * + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EINVAL + * - epd is not a valid endpoint descriptor, or + *- ENODEV + * - The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOMEM + * - Insufficient kernel memory was available. + *- ENOTTY + * - epd is not a valid endpoint descriptor + */ +int scif_fence_wait(scif_epd_t epd, int mark); + +/** + * scif_fence_signal - Request a signal on completion of RMAs + * \param loff local offset + * \param lval local value to write to loffset + * \param roff remote offset + * \param rval remote value to write to roffset + * \param flags flags + * + * scif_fence_signal() returns after marking the current set of all uncompleted + * RMAs initiated through the endpoint epd or marking the current set of all + * uncompleted RMAs initiated through the peer of endpoint epd. + * + * If flags includes SCIF_SIGNAL_LOCAL, then on completion of the RMAs in the + * marked set, lval is written to memory at the address corresponding to offset + * loff in the local registered address space of epd. loff must be within a + * registered window. If flags includes SCIF_SIGNAL_REMOTE, then on completion + * of the RMAs in the marked set, rval is written to memory at the * address + * corresponding to offset roff in the remote registered address space of epd. + * roff must be within a remote registered window of the peer of epd. Note + * that any specified offset must be DWORD (4 byte / 32 bit) aligned. + * + * The flags argument is formed by OR'ing together the following: + *- Exactly one of the following values: + * - SCIF_FENCE_INIT_SELF: RMA operations initiated through endpoint + * epd are marked + * - SCIF_FENCE_INIT_PEER: RMA operations initiated through the peer + * of endpoint epd are marked + *- One or more of the following values: + * - SCIF_SIGNAL_LOCAL: On completion of the marked set of RMAs, write lval to + * memory at the address corresponding to offset loff in the local registered + * address space of epd. + * - SCIF_SIGNAL_REMOTE: On completion of the marked set of RMAs, write lval to + * memory at the address corresponding to offset roff in the remote registered + * address space of epd. + * + *\return + * Upon successful completion, scif_fence_signal() returns 0; otherwise: in + * user mode -1 is returned and errno is set to indicate the error; in kernel + * mode the negative of one of the following errors is returned. + *\par Errors: + *- EBADF + * - epd is not a valid endpoint descriptor + *- ECONNRESET + * - A connection was forcibly closed by a peer. + *- EINVAL + * - epd is not a valid endpoint descriptor, or + * - flags is invalid, or + * - loff or roff are not DWORD aligned + *- ENODEV + * - The remote node is lost. + *- ENOTCONN + * - The endpoint is not connected + *- ENOTTY + * - epd is not a valid endpoint descriptor + *- ENXIO + * - loff is invalid for the registered address of epd, or + * - roff is invalid for the registered address space, of the peer of epd + */ +int scif_fence_signal(scif_epd_t epd, off_t loff, uint64_t lval, off_t roff, +uint64_t rval, int flags); + +/** + * scif_get_nodeIDs - Return information about online nodes + * \param nodes array in which to return online node IDs + * \param len number of entries in the nodes array + * \param self address to place the node ID of the local node + * + * scif_get_nodeIDs() fills in the nodes array with up to len node IDs of the + * nodes in the SCIF network. If there is not enough space in nodes, as + * indicated by the len parameter, only len node IDs are returned in nodes. The + * return value of scif_get_nodeID() is the total number of nodes currently in + * the SCIF network. By checking the return value against the len parameter, the user may + * determine if enough space for nodes was allocated. + * + * The node ID of the local node is returned at self. + * + *\return + * Upon successful completion, scif_get_nodeIDs() returns the actual number of + * online nodes in the SCIF network including 'self'; otherwise: in user mode + * -1 is returned and errno is set to indicate the error; in kernel mode no + * errors are returned. + * + *\par Errors: + *- EFAULT + * - Bad address + */ +int scif_get_nodeIDs(uint16_t *nodes, int len, uint16_t *self); + +/** + * scif_get_fd - Get file descriptor from endpoint descriptor + * \param epd endpoint descriptor + * + * scif_get_fd() returns the file descriptor which backs a specified endpoint + * descriptor, epd. The file descriptor returned should only be used as a + * parameter to poll() or select(). + * + *\return + * scif_get_fd() returns the file descriptor. There are no errors. + */ +static inline int scif_get_fd(scif_epd_t epd) +{ + return (int) epd; +} + + +/** + * scif_poll - Wait for some event on an endpoint + * \param epds Array of endpoint descriptors + * \param nepds Length of epds + * \param timeout Upper limit on time for which scif_poll() will + * block + * + * scif_poll() waits for one of a set of endpoints to become ready to perform + * an I/O operation. scif_poll() exposes a subset of the functionality of the + * POSIX standard poll() function. + * + * The epds argument specifies the endpoint descriptors to be examined and the + * events of interest for each endpoint descriptor. epds is a pointer to an + * array with one member for each open endpoint descriptor of interest. + * + * The number of items in the epds array is specified in nepds. The epd field + * of scif_pollepd is an endpoint descriptor of an open endpoint. The field + * events is a bitmask specifying the events which the application is + * interested in. The field revents is an output parameter, filled by the + * kernel with the events that actually occurred. The bits returned in revents + * can include any of those specified in events, or one of the values + * SCIF_POLLERR, SCIF_POLLHUP, or SCIF_POLLNVAL. (These three bits are + * meaningless in the events field, and will be set in the revents field + * whenever the corresponding condition is true.) + * + * If none of the events requested (and no error) has occurred for any of the + * endpoint descriptors, then scif_poll() blocks until one of the events occurs. + * + * The timeout argument specifies an upper limit on the time for which + * scif_poll() will block, in milliseconds. Specifying a negative value in + * timeout means an infinite timeout. + * + * The following bits may be set in events and returned in revents: + *- SCIF_POLLIN: Data may be received without blocking. For a connected + * endpoint, this means that scif_recv() may be called without blocking. For a + * listening endpoint, this means that scif_accept() may be called without + * blocking. + *- SCIF_POLLOUT: Data may be sent without blocking. For a connected endpoint, + * this means that scif_send() may be called without blocking. This bit value + * has no meaning for a listening endpoint and is ignored if specified. + * + * The following bits are only returned in revents, and are ignored if set in + * events: + *- SCIF_POLLERR: An error occurred on the endpoint + *- SCIF_POLLHUP: The connection to the peer endpoint was disconnected + *- SCIF_POLLNVAL: The specified endpoint descriptor is invalid. + * + *\return + * Upon successful completion, scif_poll()returns a non-negative value. A + * positive value indicates the total number of endpoint descriptors that have + * been selected (that is, endpoint descriptors for which the revents member is + * non-zero. A value of 0 indicates that the call timed out and no endpoint + * descriptors have been selected. Otherwise: in user mode -1 is returned and + * errno is set to indicate the error; in kernel mode the negative of one of + * the following errors is returned. + * + *\par Errors: + *- EFAULT + * - The array given as argument was not contained in the calling program's + * address space. + *- EINTR + * - A signal occurred before any requested event. + *- EINVAL + * - The nepds argument is greater than {OPEN_MAX} + *- ENOMEM + * - There was no space to allocate file descriptor tables. +*/ +int +scif_poll( + struct scif_pollepd *epds, + unsigned int nepds, + long timeout); + +/** + * scif_event_register - Register an event handler + * \param handler Event handler to be registered + * + * scif_event_register() registers a routine, handler, to be called when some + * event occurs. The event parameter to handler indicates the type of event + * which has occurred, and the corresponding component of the data parameter to + * handler provides additional data about the event. + * + * The following events are defined: + *- SCIF_NODE_ADDED: A node has been added to the SCIF network. The + * scif_node_added component of the data parameter to handler identifies the + * node. This event is informational. There are no requirements on the event + * handler. + *- SCIF_NODE_REMOVED: A node is being removed from the SCIF network. The + * scif_node_removed component of the data parameter to handler identifies the + * node. Upon being called, and before returning, the event handler must + * return, using scif_put_pages(), all structures obtained using + * scif_get_pages() against an endpoint connected to the lost node. It is + * recommended and expected that the handler will also scif_close() all + * endpoints connected to the lost node. + * + *\return + * Upon successful completion scif_event_register() returns 0. + * + *\par Errors: + *- ENOMEM + * - There was no space to allocate file descriptor tables. +*/ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __SCIF_H__ */