245 lines
8.7 KiB
C
245 lines
8.7 KiB
C
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
|
/**
|
|
* @file ft_tt_arch.h
|
|
* @brief Per-architecture description tables for Tenstorrent parts, selected at
|
|
* RUNTIME from the PCI vendor/device id the kernel driver reports.
|
|
*
|
|
* One table describes one chip family: NoC grid size, where every tile type sits
|
|
* on NoC #0, how translated coordinates are laid out, how ARC telemetry encodes
|
|
* harvesting, the host TLB windows, and the per-Tensix scalars the compiled
|
|
* memory-map headers were written against.
|
|
*
|
|
* Only Blackhole has a table. Every other Tenstorrent part (Wormhole B0,
|
|
* Grayskull) is recognised BY NAME so a refusal can say what it saw, and is then
|
|
* refused: a table nobody could check against hardware is not shipped. Inside the
|
|
* one table, a field whose value is not verified is 0, never a plausible guess.
|
|
*
|
|
* Nothing here touches a device; every function is a pure function of its
|
|
* arguments and of constant data.
|
|
*
|
|
* @status Blackhole table complete; selection, naming and both self-checks
|
|
* implemented and covered by tests/test_arch.c.
|
|
* @issues None
|
|
* @todo None
|
|
*/
|
|
|
|
#ifndef FT_TT_ARCH_H
|
|
#define FT_TT_ARCH_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
/** Chip families this module can NAME. Naming is not support: only
|
|
* FT_TT_ARCH_BLACKHOLE ever selects a table. */
|
|
typedef enum ft_tt_arch_id {
|
|
FT_TT_ARCH_UNKNOWN = 0,
|
|
FT_TT_ARCH_GRAYSKULL,
|
|
FT_TT_ARCH_WORMHOLE_B0,
|
|
FT_TT_ARCH_BLACKHOLE
|
|
} ft_tt_arch_id;
|
|
|
|
/** Which Tensix axis a part fuses off when it harvests. ft_tt_coord implements
|
|
* COLUMN only, and ft_tt_arch_check() refuses anything else. */
|
|
typedef enum ft_tt_harvest_axis {
|
|
FT_TT_HARVEST_AXIS_NONE = 0,
|
|
FT_TT_HARVEST_AXIS_ROW,
|
|
FT_TT_HARVEST_AXIS_COLUMN
|
|
} ft_tt_harvest_axis;
|
|
|
|
/** One NoC position, compact form for constant tables. */
|
|
typedef struct ft_tt_arch_xy {
|
|
uint8_t x;
|
|
uint8_t y;
|
|
} ft_tt_arch_xy;
|
|
|
|
/**
|
|
* The Tensix grid. Grid column i sits at NoC #0 x = noc_x_by_column[i]; grid row j
|
|
* at NoC #0 y = noc_y_by_row[j]. `telemetry_bit_by_column[i]` is the bit of ARC's
|
|
* enabled-columns telemetry word that reports grid column i. It must be a
|
|
* permutation of 0..column_count-1; it is NOT the identity on Blackhole.
|
|
*/
|
|
typedef struct ft_tt_arch_tensix {
|
|
uint32_t column_count;
|
|
uint32_t row_count;
|
|
ft_tt_harvest_axis harvest_axis;
|
|
const uint8_t *noc_x_by_column;
|
|
const uint8_t *noc_y_by_row;
|
|
const uint8_t *telemetry_bit_by_column;
|
|
} ft_tt_arch_tensix;
|
|
|
|
/** Upper bound on DRAM banks any table may declare. The buffer allocator keeps
|
|
* one statically sized arena per bank, so a larger part is refused at the table
|
|
* gate rather than overflowing that array. */
|
|
#define FT_TT_MAX_DRAM_BANKS 8u
|
|
|
|
/**
|
|
* DRAM banks. Each bank is reachable through `ports_per_bank` NoC tiles that all
|
|
* expose the same memory; `noc0` holds bank_count x ports_per_bank entries,
|
|
* bank-major, in port order. In translated space the banks form
|
|
* `translated_column_count` columns starting at (translated_origin_x,
|
|
* translated_origin_y), ports_per_bank consecutive y per bank.
|
|
*/
|
|
typedef struct ft_tt_arch_dram {
|
|
uint32_t bank_count;
|
|
uint32_t ports_per_bank;
|
|
uint32_t max_harvested_banks;
|
|
const ft_tt_arch_xy *noc0;
|
|
uint32_t translated_origin_x;
|
|
uint32_t translated_origin_y;
|
|
uint32_t translated_column_count;
|
|
} ft_tt_arch_dram;
|
|
|
|
/** Ethernet tiles, indexed by channel. Enabled channels are packed, in channel
|
|
* order, along one translated row starting at the translated origin. */
|
|
typedef struct ft_tt_arch_eth {
|
|
uint32_t channel_count;
|
|
const ft_tt_arch_xy *noc0;
|
|
uint32_t translated_origin_x;
|
|
uint32_t translated_origin_y;
|
|
} ft_tt_arch_eth;
|
|
|
|
/**
|
|
* Tiles that are never harvested-and-renumbered by Foundry: ARC, the security
|
|
* tile, the PCIe endpoints, the L2CPU clusters, and router-only NoC nodes.
|
|
* `l2cpu_noc0` lists L2CPU tiles in Foundry's logical order;
|
|
* `l2cpu_telemetry_bit_by_tile[t]` is the enabled-L2CPU telemetry bit for tile t.
|
|
* `pcie_translated` is the single translated alias of whichever PCIe tile is in
|
|
* use on the board.
|
|
*/
|
|
typedef struct ft_tt_arch_fixed_blocks {
|
|
ft_tt_arch_xy arc;
|
|
ft_tt_arch_xy security;
|
|
uint32_t security_count;
|
|
uint32_t pcie_count;
|
|
const ft_tt_arch_xy *pcie_noc0;
|
|
ft_tt_arch_xy pcie_translated;
|
|
uint32_t l2cpu_count;
|
|
const ft_tt_arch_xy *l2cpu_noc0;
|
|
const uint8_t *l2cpu_telemetry_bit_by_tile;
|
|
uint32_t router_count;
|
|
const ft_tt_arch_xy *router_noc0;
|
|
} ft_tt_arch_fixed_blocks;
|
|
|
|
/** NoC coordinate space size (nodes, not cores). */
|
|
typedef struct ft_tt_arch_noc {
|
|
uint32_t size_x;
|
|
uint32_t size_y;
|
|
} ft_tt_arch_noc;
|
|
|
|
/** Host-to-device TLB windows exposed through the PCIe BARs. */
|
|
typedef struct ft_tt_arch_tlb {
|
|
uint32_t window_2m_count;
|
|
uint32_t window_4g_count;
|
|
uint32_t kernel_window_index;
|
|
uint32_t register_stride_bytes;
|
|
uint32_t registers_offset;
|
|
uint32_t registers_length;
|
|
uint32_t strided_window_count;
|
|
} ft_tt_arch_tlb;
|
|
|
|
/** Where ARC publishes its telemetry table, and the tag ids of the five grid
|
|
* facts Foundry reads from it. */
|
|
typedef struct ft_tt_arch_telemetry {
|
|
uint32_t scratch_base;
|
|
uint32_t table_pointer_scratch_index;
|
|
uint32_t values_pointer_scratch_index;
|
|
uint32_t csm_base;
|
|
uint32_t csm_size;
|
|
uint16_t tag_enabled_tensix_col;
|
|
uint16_t tag_enabled_eth;
|
|
uint16_t tag_enabled_gddr;
|
|
uint16_t tag_enabled_l2cpu;
|
|
uint16_t tag_noc_translation;
|
|
} ft_tt_arch_telemetry;
|
|
|
|
/**
|
|
* Per-Tensix scalars. The second group (programmable_core_type_count through
|
|
* circular_buffer_count) is the firmware-interface contract ft_tt_mailbox.h's
|
|
* struct layout is derived from; ft_tt_arch_check_headers() compares those and
|
|
* the memory-map scalars against the compiled headers.
|
|
*/
|
|
typedef struct ft_tt_arch_tensix_core {
|
|
uint32_t processor_count;
|
|
bool has_ncrisc_iram;
|
|
|
|
uint32_t programmable_core_type_count;
|
|
uint32_t max_num_kernels;
|
|
uint32_t subordinate_map_size;
|
|
uint32_t processors_for_threading_variables;
|
|
uint32_t circular_buffer_count;
|
|
|
|
uint32_t l1_size;
|
|
uint32_t l1_alignment;
|
|
uint32_t dram_alignment;
|
|
uint64_t dram_bytes_per_bank;
|
|
uint32_t mailbox_base;
|
|
uint32_t soft_reset_address;
|
|
uint32_t soft_reset_all_riscs_mask;
|
|
uint32_t noc_overlay_base;
|
|
uint32_t noc_stream_register_span;
|
|
uint32_t tile_height;
|
|
uint32_t tile_width;
|
|
uint32_t faces_per_tile;
|
|
} ft_tt_arch_tensix_core;
|
|
|
|
/** One architecture. All pointers reference static constant storage. */
|
|
typedef struct ft_tt_arch {
|
|
ft_tt_arch_id id;
|
|
const char *name;
|
|
uint16_t pci_vendor_id;
|
|
const uint16_t *pci_device_ids;
|
|
uint32_t pci_device_id_count;
|
|
uint64_t kmd_chip_arch;
|
|
ft_tt_arch_noc noc;
|
|
ft_tt_arch_tensix tensix;
|
|
ft_tt_arch_dram dram;
|
|
ft_tt_arch_eth eth;
|
|
ft_tt_arch_fixed_blocks fixed;
|
|
ft_tt_arch_tlb tlb;
|
|
ft_tt_arch_telemetry telemetry;
|
|
ft_tt_arch_tensix_core core;
|
|
} ft_tt_arch;
|
|
|
|
/** The Blackhole table. Static storage, never NULL, never freed. */
|
|
const ft_tt_arch *ft_tt_arch_blackhole(void);
|
|
|
|
/** Name the family a Tenstorrent PCI device id belongs to, supported or not.
|
|
* Unrecognised ids are FT_TT_ARCH_UNKNOWN. */
|
|
ft_tt_arch_id ft_tt_arch_id_for_pci_device_id(uint16_t pci_device_id);
|
|
|
|
/** Printable family name. Never NULL, including for out-of-range values. */
|
|
const char *ft_tt_arch_id_string(ft_tt_arch_id id);
|
|
|
|
/**
|
|
* Select the table for a device, cross-checked against the kernel driver's own
|
|
* chip_arch value. Returns NULL (reason logged) for a wrong vendor, an
|
|
* unsupported or unknown device id, a driver opinion that disagrees with the
|
|
* device id, or a table that fails ft_tt_arch_check() / ft_tt_arch_check_headers().
|
|
*/
|
|
const ft_tt_arch *ft_tt_arch_select(uint16_t pci_vendor_id, uint16_t pci_device_id,
|
|
uint64_t kmd_chip_arch);
|
|
|
|
/** As ft_tt_arch_select() without the driver cross-check, for paths that read the
|
|
* ids straight from PCI config space with no kernel driver bound. */
|
|
const ft_tt_arch *ft_tt_arch_select_by_pci_ids(uint16_t pci_vendor_id, uint16_t pci_device_id);
|
|
|
|
/**
|
|
* Structural self-check of a table: identity present, harvest axis is COLUMN,
|
|
* bit-order tables are permutations, masks fit 32 bits, every coordinate lies
|
|
* inside the NoC grid, DRAM banks divide into the alias columns and fit
|
|
* FT_TT_MAX_DRAM_BANKS, TLB and reset descriptions non-empty.
|
|
*
|
|
* @return FT_TT_OK, FT_TT_EINVAL (NULL), or FT_TT_EIO (reason logged).
|
|
*/
|
|
int ft_tt_arch_check(const ft_tt_arch *arch);
|
|
|
|
/**
|
|
* Check that the compiled single-part headers (ft_tt_memmap.h, ft_tt_mailbox.h,
|
|
* ft_tt_launch.h, ft_tt_device.h) describe the same part as `arch`.
|
|
*
|
|
* @return FT_TT_OK, FT_TT_EINVAL (NULL), or FT_TT_EIO (first mismatch logged).
|
|
*/
|
|
int ft_tt_arch_check_headers(const ft_tt_arch *arch);
|
|
|
|
#endif
|