NHP & LSTP messaging

Beyond the DMTF stacks (PLDM, SPDM), OpenSMA carries a few smaller, NVIDIA-specific messaging paths. This page is a catalog: each gets a short subsection covering its role and key files.

NHP — E.1S hot-swap handler

src/nv/nhp/ implements the drive-bay hot-swap handler. The controller presents itself to a host as a bank of PCA9555 GPIO expanders over an I2C-slave interface; the host reads/writes a 16-bit control register per E.1S drive to drive PERST#, clock enable, power enable/disable, and the amber/blue status LEDs.

  • NHP class (src/nv/nhp/nhp.h:44) owns the per-drive I2C-slave driver, GPIO-expander emulators, and the hot-swap state machines. The I2C-slave driver dispatches transactions to NHP::i2c_callback (src/nv/nhp/nhp.cpp:140), which routes register reads/writes to the right drive index.
  • Hot-swap state machineNhpE1sHotSwap (src/nv/nhp/hssm.h:26) tracks DriveDisabled / HostControl / PowerFault per drive. update_control_register (src/nv/nhp/hssm.cpp:42) applies the host’s 16-bit pin-control vector onto the physical GPIO pins.
  • Register bit map — the control-register bit assignments (PERST#, clock-enable, present, LEDs, power-enable/disable, power-good) are defined in src/nv/nhp/common.h:64.
  • Tasknv::nhp::Task (src/nv/nhp/task.h) runs an ADC polling loop for 12 V power-good monitoring (src/nv/nhp/task.cpp:66) and forwards GPIO / ADC interrupts into the NHP instances.

Interpretation: NHP is a GPIO/power-sequencing protocol for E.1S NVMe bays rather than a message-transport like MCTP; the “protocol” is the PCA9555 register layout the host drives over I2C.

LSTP — channel-multiplexed request/response

LSTP is a lightweight request/response protocol that multiplexes several logical channels (management, SPI, GPIO, I2C, UART, IPMI) over a single link — primarily USB. It is split into a shared parser (src/nv/lstp/) and a bare-metal router (src/nv/lstp_bm/).

  • Wire format — every message starts with a 4-byte LstpHdr (src/nv/lstp/lstp_common.h:146): channel_id, cmd_status_code (bit 7 flags request vs. response, LstpResponseBit), and a 16-bit length. Channel types are enumerated at src/nv/lstp/lstp_common.h:63 and status codes at src/nv/lstp/lstp_common.h:84; the max message size is 512 bytes.
  • ParserLstpParser (src/nv/lstp/lstp_parser.h:27) is transport-agnostic. validate_request (src/nv/lstp/lstp_parser.cpp:24) bounds-checks the header/length, parse_channel_type (src/nv/lstp/lstp_parser.cpp:53) resolves the configured channel (including the flashrom channel-0 SPI alias), and parse_spi_request (src/nv/lstp/lstp_parser.cpp:80) decodes SPI read/write/write-read commands.
  • Bare-metal routernv::lstp::bm::LstpRouter (src/nv/lstp_bm/lstp_router.h:27) runs inside the USB stack. receive (src/nv/lstp_bm/lstp_router.cpp:31) switches on the parsed channel type and forwards to receive_spi (which drives the bare-metal SpiManager) or receive_i2c; send_error (src/nv/lstp_bm/lstp_router.cpp:55) and send_spi write responses back into the USB LSTP TX buffers.
  • RTOS-side router / task — a fuller LstpRouter (src/nv/lstp/lstp_router.h:59) handles the remaining channel types, and LstpTask (src/nv/lstp/lstp_task.h:60) provides the event-driven GPIO channel (submit_gpio_req / submit_gpio_irq).

IPC handler — inter-task dispatch

src/nv/ipchandler/ is the small router that moves a message from one task to another task’s queue. It is the mechanism PLDM and SPDM use to exchange firmware-authentication requests and results without sharing state.

  • Endpointsnv::ipchandler::Id (src/nv/ipchandler/enums.h:30) enumerates the addressable tasks/queues: Mctp, I2c0I2c9, I3c0/I3c1, Pldm, Usb, Flash, Logger, Spdm, Iox, Lstp.
  • DriverDriver::send (src/nv/ipchandler/ipchandler.cpp:26) wraps the payload in a Header (src/nv/ipchandler/ipchandler.h:27 — source/dest id, size, request flag) and calls Driver::handler (src/nv/ipchandler/ipchandler.cpp:53), which switches on dst_id and forwards to the matching I3C / I2C / USB / PLDM queue.
  • Callers — the PLDM task’s Task::to_pldm and the SPDM→PLDM authentication-result path both go through this handler (see PLDM).

Where to look next


Built with Just the Docs. Source-traced against NVIDIA/OpenSMA at 9b183d3 (v02.0020.0000). Methodology under appendices/trace-methodology.

This site uses Just the Docs, a documentation theme for Jekyll.