Foundry/tt/ft_tt_kmd_abi.h

277 lines
11 KiB
C

/* SPDX-License-Identifier: AGPL-3.0-or-later */
/**
* @file ft_tt_kmd_abi.h
* @brief The Tenstorrent kernel driver's ioctl ABI on /dev/tenstorrent/N, as Foundry names:
* request codes, mapping ids, power-word bits and the exact byte layout of every argument
* struct Foundry passes. Numbers only; no behaviour. ft_tt_kmd.c is the one consumer that
* issues these on the backend path; card tests that drive the driver directly also use them.
*
* Little-endian, natural alignment. Every struct is the WHOLE argument the ioctl pointer
* refers to, and every size and load-bearing offset is checked at compile time below, so a
* layout slip is a build error rather than a wrong request on the wire.
*
* @status Covers the eight commands Foundry issues: device info, query mappings, driver info,
* allocate / free / configure window, close-time NoC write, power state.
* @issues None
* @todo None
*/
#ifndef FT_TT_KMD_ABI_H
#define FT_TT_KMD_ABI_H
#include <stddef.h>
#include <stdint.h>
/* ================================================================
* Request codes: (0xFA << 8) | n — Linux _IO(0xFA, n), no size or direction bits
* ================================================================ */
#define FT_TT_KMD_IOCTL_MAGIC 0xFAu
#define FT_TT_KMD_IOCTL_CODE(command) ((unsigned long)((FT_TT_KMD_IOCTL_MAGIC << 8) | (command)))
#define FT_TT_KMD_IOCTL_GET_DEVICE_INFO FT_TT_KMD_IOCTL_CODE(0u)
#define FT_TT_KMD_IOCTL_QUERY_MAPPINGS FT_TT_KMD_IOCTL_CODE(2u)
#define FT_TT_KMD_IOCTL_GET_DRIVER_INFO FT_TT_KMD_IOCTL_CODE(5u)
#define FT_TT_KMD_IOCTL_ALLOCATE_WINDOW FT_TT_KMD_IOCTL_CODE(11u)
#define FT_TT_KMD_IOCTL_FREE_WINDOW FT_TT_KMD_IOCTL_CODE(12u)
#define FT_TT_KMD_IOCTL_CONFIGURE_WINDOW FT_TT_KMD_IOCTL_CODE(13u)
/** Register a NoC write the driver performs when the fd is closed ("noc cleanup"). */
#define FT_TT_KMD_IOCTL_NOC_CLEANUP FT_TT_KMD_IOCTL_CODE(14u)
#define FT_TT_KMD_IOCTL_SET_POWER_STATE FT_TT_KMD_IOCTL_CODE(15u)
/* Used only by tools and card tests, each with its own argument layout or the one below. */
#define FT_TT_KMD_IOCTL_ALLOCATE_DMA_BUF FT_TT_KMD_IOCTL_CODE(3u)
#define FT_TT_KMD_IOCTL_RESET_DEVICE FT_TT_KMD_IOCTL_CODE(6u)
#define FT_TT_KMD_IOCTL_SMC_MESSAGE FT_TT_KMD_IOCTL_CODE(17u)
/** The ioctl API version this code speaks. */
#define FT_TT_KMD_ABI_VERSION 2u
/* ================================================================
* Identity
* ================================================================ */
#define FT_TT_KMD_PCI_DEVICE_ID_BLACKHOLE 0xB140u
#define FT_TT_KMD_PCI_DEVICE_ID_WORMHOLE 0x401Eu
/* ================================================================
* Mapping ids (QUERY_MAPPINGS). resource0 = BAR0, resource1 = BAR2, resource2 = BAR4.
* ================================================================ */
#define FT_TT_KMD_MAPPING_UNUSED 0u
#define FT_TT_KMD_MAPPING_RESOURCE0_UC 1u
#define FT_TT_KMD_MAPPING_RESOURCE0_WC 2u
#define FT_TT_KMD_MAPPING_RESOURCE1_UC 3u
#define FT_TT_KMD_MAPPING_RESOURCE1_WC 4u
#define FT_TT_KMD_MAPPING_RESOURCE2_UC 5u
#define FT_TT_KMD_MAPPING_RESOURCE2_WC 6u
/** How many mapping records Foundry asks for: one UC and one WC per resource. */
#define FT_TT_KMD_MAPPING_QUERY_COUNT 6u
/* ================================================================
* Power word (SET_POWER_STATE)
* ================================================================ */
#define FT_TT_KMD_POWER_FLAG_MAX_AI_CLOCK 0x0001u /**< 1 = max AI clock, 0 = min */
#define FT_TT_KMD_POWER_FLAG_MEMORY_PHY_AWAKE 0x0002u
#define FT_TT_KMD_POWER_FLAG_TENSIX_ENABLE 0x0004u
#define FT_TT_KMD_POWER_FLAG_L2CPU_ENABLE 0x0008u
/** Every flag bit the word carries. */
#define FT_TT_KMD_POWER_FLAGS_ALL 0x7FFFu
/** The validity byte: low nibble = number of valid flag bits, high nibble = number of valid
* settings. */
#define FT_TT_KMD_POWER_VALIDITY(flag_count, setting_count) \
((((unsigned)(setting_count) & 0xFu) << 4) | ((unsigned)(flag_count) & 0xFu))
#define FT_TT_KMD_POWER_SETTING_COUNT 14u
/* ================================================================
* Argument structs
* ================================================================ */
/** GET_DEVICE_INFO (0). The caller sets in.out_size to sizeof(out). */
struct ft_tt_kmd_device_info_request {
struct {
uint32_t out_size;
} in;
struct {
uint32_t out_size;
uint16_t vendor_id;
uint16_t device_id;
uint16_t subsystem_vendor_id;
uint16_t subsystem_id;
uint16_t bdf; /**< bits 0-2 function, 3-7 device, 8-15 bus */
uint16_t max_dma_log2;
uint16_t pci_domain;
uint16_t reserved;
} out;
};
/** QUERY_MAPPINGS (2) header. `count` records of ft_tt_kmd_mapping follow it directly. */
struct ft_tt_kmd_query_mappings_in {
uint32_t count;
uint32_t reserved;
};
/** One QUERY_MAPPINGS record. */
struct ft_tt_kmd_mapping {
uint32_t id; /**< FT_TT_KMD_MAPPING_* */
uint32_t reserved;
uint64_t base; /**< an mmap offset on the chardev */
uint64_t size; /**< bytes */
};
/** QUERY_MAPPINGS as Foundry issues it: the header plus six records. */
struct ft_tt_kmd_query_mappings_request {
struct ft_tt_kmd_query_mappings_in in;
struct ft_tt_kmd_mapping mappings[FT_TT_KMD_MAPPING_QUERY_COUNT];
};
/** GET_DRIVER_INFO (5). The caller sets in.out_size to sizeof(out). */
struct ft_tt_kmd_driver_info_request {
struct {
uint32_t out_size;
} in;
struct {
uint32_t out_size;
uint32_t api_version;
uint8_t major;
uint8_t minor;
uint8_t patch;
uint8_t reserved;
} out;
};
/** ALLOCATE_WINDOW (11). */
struct ft_tt_kmd_allocate_window_request {
struct {
uint64_t size;
uint64_t reserved;
} in;
struct {
uint32_t id;
uint32_t reserved0;
uint64_t mmap_offset_uc;
uint64_t mmap_offset_wc;
uint64_t reserved1;
} out;
};
/** FREE_WINDOW (12). */
struct ft_tt_kmd_free_window_request {
struct {
uint32_t id;
uint32_t reserved;
} in;
};
/** Where a window points: the 32-byte target inside CONFIGURE_WINDOW. */
struct ft_tt_kmd_window_config {
uint64_t addr;
uint16_t x_end;
uint16_t y_end;
uint16_t x_start;
uint16_t y_start;
uint8_t noc;
uint8_t mcast;
uint8_t ordering;
uint8_t linked;
uint8_t static_vc;
uint8_t reserved0[3];
uint32_t reserved1[2];
};
/** CONFIGURE_WINDOW (13). */
struct ft_tt_kmd_configure_window_request {
struct {
uint32_t id;
uint32_t reserved;
struct ft_tt_kmd_window_config config;
} in;
struct {
uint64_t reserved;
} out;
};
/** NOC_CLEANUP (14): the write the driver performs at close. argsz = 32, flags = 0. */
struct ft_tt_kmd_noc_cleanup_request {
uint32_t argsz;
uint32_t flags;
uint8_t enabled;
uint8_t x;
uint8_t y;
uint8_t noc;
uint32_t reserved;
uint64_t addr;
uint64_t data;
};
/** SET_POWER_STATE (15). argsz = 40, flags = 0. */
struct ft_tt_kmd_power_state_request {
uint32_t argsz;
uint32_t flags;
uint8_t reserved;
uint8_t validity; /**< FT_TT_KMD_POWER_VALIDITY(flags, settings) */
uint16_t flags_word; /**< FT_TT_KMD_POWER_FLAG_* */
uint16_t settings[FT_TT_KMD_POWER_SETTING_COUNT];
};
/** Driver-relayed ARC message (cmd 17), 48 bytes. Card tests use it as an independent path. */
#define FT_TT_KMD_SMC_MESSAGE_POST (1u << 0)
#define FT_TT_KMD_SMC_MESSAGE_POLL (1u << 1)
#define FT_TT_KMD_SMC_MESSAGE_ABANDON (1u << 2)
#define FT_TT_KMD_SMC_MESSAGE_WORDS 8u
struct ft_tt_kmd_smc_message {
uint32_t argsz; /**< 48 */
uint32_t flags; /**< FT_TT_KMD_SMC_MESSAGE_* */
uint32_t queue; /**< must be 0 */
uint32_t reserved; /**< must be 0 */
uint32_t words[FT_TT_KMD_SMC_MESSAGE_WORDS]; /**< request on POST, reply on a good POLL */
};
/* ================================================================
* Layout checks (C99 has no _Static_assert: a negative array size is the error)
* ================================================================ */
#define FT_TT_KMD_ABI_CHECK(name, condition) \
typedef char ft_tt_kmd_abi_check_##name[(condition) ? 1 : -1]
FT_TT_KMD_ABI_CHECK(device_info_size, sizeof(struct ft_tt_kmd_device_info_request) == 24);
FT_TT_KMD_ABI_CHECK(device_info_out_at_4,
offsetof(struct ft_tt_kmd_device_info_request, out) == 4);
FT_TT_KMD_ABI_CHECK(device_info_out_size,
sizeof(((struct ft_tt_kmd_device_info_request *)0)->out) == 20);
FT_TT_KMD_ABI_CHECK(query_in_size, sizeof(struct ft_tt_kmd_query_mappings_in) == 8);
FT_TT_KMD_ABI_CHECK(mapping_size, sizeof(struct ft_tt_kmd_mapping) == 24);
FT_TT_KMD_ABI_CHECK(mapping_base_at_8, offsetof(struct ft_tt_kmd_mapping, base) == 8);
FT_TT_KMD_ABI_CHECK(mapping_size_at_16, offsetof(struct ft_tt_kmd_mapping, size) == 16);
FT_TT_KMD_ABI_CHECK(query_request_size,
sizeof(struct ft_tt_kmd_query_mappings_request) == 8 + 6 * 24);
FT_TT_KMD_ABI_CHECK(driver_info_size, sizeof(struct ft_tt_kmd_driver_info_request) == 16);
FT_TT_KMD_ABI_CHECK(driver_info_out_size,
sizeof(((struct ft_tt_kmd_driver_info_request *)0)->out) == 12);
FT_TT_KMD_ABI_CHECK(allocate_size, sizeof(struct ft_tt_kmd_allocate_window_request) == 48);
FT_TT_KMD_ABI_CHECK(allocate_out_at_16,
offsetof(struct ft_tt_kmd_allocate_window_request, out) == 16);
FT_TT_KMD_ABI_CHECK(free_size, sizeof(struct ft_tt_kmd_free_window_request) == 8);
FT_TT_KMD_ABI_CHECK(window_config_size, sizeof(struct ft_tt_kmd_window_config) == 32);
FT_TT_KMD_ABI_CHECK(window_config_noc_at_16,
offsetof(struct ft_tt_kmd_window_config, noc) == 16);
FT_TT_KMD_ABI_CHECK(configure_size, sizeof(struct ft_tt_kmd_configure_window_request) == 48);
FT_TT_KMD_ABI_CHECK(configure_config_at_8,
offsetof(struct ft_tt_kmd_configure_window_request, in.config) == 8);
FT_TT_KMD_ABI_CHECK(configure_out_at_40,
offsetof(struct ft_tt_kmd_configure_window_request, out) == 40);
FT_TT_KMD_ABI_CHECK(noc_cleanup_size, sizeof(struct ft_tt_kmd_noc_cleanup_request) == 32);
FT_TT_KMD_ABI_CHECK(noc_cleanup_addr_at_16,
offsetof(struct ft_tt_kmd_noc_cleanup_request, addr) == 16);
FT_TT_KMD_ABI_CHECK(power_state_size, sizeof(struct ft_tt_kmd_power_state_request) == 40);
FT_TT_KMD_ABI_CHECK(power_state_settings_at_12,
offsetof(struct ft_tt_kmd_power_state_request, settings) == 12);
FT_TT_KMD_ABI_CHECK(smc_message_size, sizeof(struct ft_tt_kmd_smc_message) == 48);
FT_TT_KMD_ABI_CHECK(smc_message_words_at_16, offsetof(struct ft_tt_kmd_smc_message, words) == 16);
#endif /* FT_TT_KMD_ABI_H */