Platform Support

Bringing FBOSS up on a new switch is mostly a matter of data: CSV and JSON files that describe the board's wiring, its port profiles, its ASIC settings, and its platform devices. This page explains the layout of fboss/configs/platforms/, the platform mapping and how it is generated, the ASIC config generators, the platform stack configs, the config-driven path that needs no new C++ for standard platforms, and the validation steps a vendor goes through before submitting a pull request.

The Platform Directory

Every platform lives in fboss/configs/platforms/<vendor>/<platform>/. Using celestica/montblanc as an example:

fboss/configs/platforms/celestica/montblanc/
├── platform_mapping/            # Board wiring and port profiles (vendor-provided)
│   ├── montblanc_static_mapping.csv
│   ├── montblanc_si_settings.csv
│   ├── montblanc_port_profile_mapping.csv
│   ├── montblanc_profile_settings.csv
│   ├── montblanc_platform_descriptor.csv
│   ├── montblanc_vendor_config.json
│   └── generated/               # Output of the generator: never edit by hand
├── asic_config/                 # ASIC (SDK/SAI) settings for this board
│   ├── asic_config.json
│   └── generated/
├── forwarding_stack/            # Agent config generation inputs
│   ├── config_generation.json
│   ├── link_topology/
│   └── generated/
├── platform_stack/              # Platform services configs
│   ├── platform_manager.json
│   ├── sensor_service.json
│   ├── fan_service.json
│   ├── fw_util.json
│   ├── led_manager.json
│   ├── bsp_tests.json
│   └── rma_showtech.json
└── variants/                    # Variants that override some of the inputs

Rules from the repository's contributor guidance:

  • Edit the CSVs in platform_mapping/ (or variants/<variant>/platform_mapping/), never anything under generated/.
  • <platform>_vendor_config.json sits beside the CSVs but is hand-maintained, not generated.
  • Never edit files marked @generated.

Platform Mapping

The platform mapping is a JSON document, built into the agent and qsfp_service binaries, that describes every port: which ASIC core and lanes it uses, lane swaps and polarities, which transceiver it belongs to, which port profiles (speed, lane count, FEC, media) it supports, and the signal integrity settings for each profile. It is generated from these vendor-provided files:

File Contents
PLATFORM_static_mapping.csv Every A-to-Z pin connection on the board (NPU, external PHY, transceiver), with TX/RX lane IDs and polarity swaps, independent of speed
PLATFORM_si_settings.csv Signal integrity values (pre, main, post taps, ...) per port and SerDes speed, optionally per media type (copper or optic) and copper cable length
PLATFORM_port_profile_mapping.csv Which ports exist and which PortProfileID profiles each supports
PLATFORM_profile_settings.csv Per speed and A-to-Z connection: lanes used, modulation, FEC, interface type
PLATFORM_vendor_config.json Vendor-specific settings passed to the SAI SDK at ASIC init that cannot be derived from the CSVs (not lane swaps or polarity)
PLATFORM_platform_descriptor.csv One row describing the platform's identity for config-driven detection: System_Vendor, Platform_Type (a PlatformType enum name), Product_Name_Prefixes (from FRUID), Mode_Names (--mode values), Asic_Type

The CSVs share column definitions such as A_SLOT_ID, A_CHIP_ID, A_CHIP_TYPE, A_CORE_ID, A_CORE_TYPE, A_CORE_LANE, A_PHYSICAL_TX_LANE, A_TX_POLARITY_SWAP (and the Z_ equivalents), PORT_SPEED (Mbps), LOGICAL_PORTID (per chip), GLOBAL_PORTID (across chips), MEDIA_TYPE (COPPER, OPTIC, or empty for both), and CABLE_LENGTH (meters, copper only). The enum values are defined in fboss/lib/platform_mapping_v2/platform_mapping_config.thrift, fboss/agent/switch_config.thrift, and fboss/lib/phy/phy.thrift.

Generating It

Run the helper from the repository root:

./fboss/lib/platform_mapping_v2/run-helper.sh --platform-name montblanc

The helper is a thin wrapper that runs python3 fboss/lib/oss/run-helper.py --target fboss-platform-mapping-gen --fboss-root fboss with your arguments, so it builds and runs the fboss-platform-mapping-gen tool.

Argument Meaning
--platform-name NAME Required. The prefix of the CSV files (montblanc in montblanc_static_mapping.csv)
--fboss-root PATH Path to the fboss/ source directory (supplied by the helper)
--input-dir DIR Platform config root (default: FBOSS_ROOT/configs/platforms/)
--output-dir DIR Write all mappings under <output-dir>/<vendor>/<platform-or-variant>/platform_mapping.json instead of beside the inputs
--multi-npu Generate a multi-NPU platform mapping (default: false)

Without --output-dir, output goes to platform_mapping/generated/ beside the inputs (and variants/<variant>/platform_mapping/generated/ for variants). Variant input directories only need the files that differ; the others are inherited from the base platform. When a descriptor CSV is present, the tool writes both platform_mapping.json and platform_descriptor.json. The descriptor's numSwitchAsics is derived by counting unique (slot_id, chip_id) pairs with chip type NPU in the static mapping.

Testing a Mapping Without Rebuilding

Normally the mapping is compiled into the binaries. For bring-up you can point the binaries at a file instead:

Flag Effect
--platform_mapping_override_path FILE Use this platform mapping JSON (agent, qsfp_service, tests)
--bsp_platform_mapping_override_path FILE Use this BSP mapping JSON (qsfp_service, led_service, tests)
--platform_descriptor_config_path ROOT Config-driven detection: scan ROOT recursively for platform_descriptor.json files (each directory must also contain platform_mapping.json); empty by default, meaning the legacy embedded mapping and hard-coded detection

run_test.py passes the two override flags through (see Running Tests), and the packaged share/platform_descriptors/ tree is linked to /tmp/platform_descriptors by the runner.

BSP Mapping

qsfp_service and led_service also need to know how to reach each transceiver and LED. That BSP mapping is derived directly from the platform's platform_manager.json; there is no separate input. For transceiver N, PlatformManager creates device nodes under /run/devmap/xcvrs/ keyed by the same index, for example xcvr_io_N (the I2C data path used to read and write module memory) and xcvr_ctrl_N (exposing xcvr_reset_N and xcvr_present_N). LED lane mapping is derived from fields such as lanesPerPort and ledPerPort.

ASIC Config

The ASIC config holds the SDK and SAI initialization settings for the switch chip (for Broadcom, the YAML or SOC properties that end up in the agent config's platform section). Two generators exist:

  • asic_config_v3 (fboss/lib/asic_config_v3/), data-driven and the successor: a generic generator per ASIC family reads layered JSON (OCP SAI common defaults in fboss/configs/asic_vendors/common/, vendor family files and per-ASIC files in fboss/configs/asic_vendors/<vendor>/<family>/, and the platform's asic_config/asic_config.json), takes lane and polarity maps from the platform mapping, and writes <variant>.yml for Broadcom XGS or <variant>.json (flat SOC properties) for Broadcom DNX. Adding a platform on an existing ASIC family needs no code.
  • asic_config_v2 (fboss/lib/asic_config_v2/), the older code-driven generator with one Python module per platform (montblanc.py, icecube800bc.py, ...), run with ./fboss/lib/asic_config_v2/run-helper.sh. Its generate_agent_config_from_asic_config.py helps build an agent config from the generated ASIC config.

Agent Config Generation

forwarding_stack/config_generation.json drives fboss2 config gen agent, which writes agent configs into forwarding_stack/generated/. CI checks that the checked-in output is current (--verify). See Agent Configuration.

Platform Stack Configs

platform_stack/*.json configure the platform services and tools (see Platform Services). Their schemas are the Thrift files of each service, for example fboss/platform/platform_manager/platform_manager_config.thrift. A generic sample is in fboss/configs/platforms/generic/sample/platform_stack/. The platform must report its name through dmidecode -s system-product-name, and every PCI device (such as FPGAs) needs a unique vendor and device ID.

Code Changes for a New Platform

With a platform descriptor, a standard platform needs no per-platform C++ in the agent:

  1. Add one entry to the PlatformType enum in fboss/lib/if/fboss_common.thrift. This is the only required Thrift change, kept because the enum is used across RPCs, FSDB, and DSF node configs.
  2. Generate the platform mapping and descriptor as above.
  3. Deploy them under <root>/<system_vendor>/<platform_name>/ and start the binaries with --platform_descriptor_config_path <root>. At start-up, PlatformDescriptorRegistry indexes descriptors by product-name prefix and mode name, PlatformProductInfo::initMode() resolves the PlatformType (falling back to the legacy detection chains), and the SAI platform init loads the external mapping and picks GenericSaiBcmPlatform or GenericSaiTajoPlatform from the descriptor's ASIC type.
  4. Make sure the ASIC is supported. Per-ASIC constants now live on the HwAsic subclasses in fboss/agent/hw/switch_asics/. A new ASIC needs a new or extended ASIC class.
  5. Only for non-standard behavior, add a dedicated platform or port subclass.

Manual Path

Without a descriptor, or for custom platforms, platforms are wired by hand: platform type detection in PlatformProductInfo (from fruid.json product names or --mode), per-platform agent classes, and per-platform qsfp_service classes that select the right platform mapping and BSP mapping. Many of these branches have been superseded by the generic classes; the repo's new platform support guide lists the touch points.

If you introduce a new platform, also add its name to fboss/lib/platform_mapping_v2/test/verify_generated_files.py.

Validation Workflow

  1. Generate the platform mapping and check that it is valid JSON.
  2. Bring up qsfp_service and the agent with --platform_mapping_override_path (or --platform_descriptor_config_path).
  3. Run the T0 tests: platform, BSP, agent HW, SAI, QSFP, then link tests. See Test Suites.
  4. Submit the inputs and generated files in a pull request. CI workflows such as platform-mapping-verification.yml and agent-config-generation-verification.yml check that generated files match their inputs.

See Also