THEORY OF OPERATION(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ¦‹ Theory of operation πŸ¦‹

okay so bestie, welcome to Theory of operation(9) from the Kernel API Manual β€” this is the SCMI Raw mode lore, and it’s actually iconic once you get the vibe. πŸ’…

When enabled, SCMI Raw mode support exposes a userspace API that lets a user application send and receive SCMI commands, replies, and notifications by injecting and snooping bare SCMI messages in binary little-endian format. Yes, we’re down at the bare-message level. No cap.

Those injected SCMI transactions then get routed through the SCMI core stack toward the SCMI backend server, using whatever SCMI transport is currently configured on the system under test. ✨

It’s meant to help run any sort of SCMI backend server testing, no matter where the server is placed, as long as it’s normally reachable via the transport configured on the system. That’s the whole point, fr fr.

Big warning energy: this is activated by a Kernel configuration option because it is NOT meant to be used in production β€” only during development and in CI deployments. Do not bring this to the production function, bestie. 😭

🌸 regular drivers vs raw mode 🌸

So to avoid possible interferences between SCMI Raw transactions originated from a test-suite and the normal operations of the SCMI drivers, there’s a default vibe: when Raw mode is enabled, by default all the regular SCMI drivers are inhibited, unless CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX is enabled.

In that coexistence case, the regular SCMI stack drivers will be loaded as usual β€” and it is up to the user of this interface to take care of manually inhibiting the regular SCMI drivers in order to avoid interferences during the test runs. That’s on you, bestie. 🫢


πŸŽ€ the exposed API πŸŽ€

The exposed API is as follows.

All SCMI Raw entries are rooted under a common top /raw debugfs directory, which in turn is rooted under the corresponding underlying SCMI instance.

/sys/kernel/debug/scmi/
`-- 0
    |-- atomic_threshold_us
    |-- instance_name
    |-- raw
    |   |-- channels
    |   |   |-- 0x10
    |   |   |   |-- message
    |   |   |   `-- message_async
    |   |   `-- 0x13
    |   |       |-- message
    |   |       `-- message_async
    |   |-- errors
    |   |-- message
    |   |-- message_async
    |   |-- notification
    |   `-- reset
    `-- transport
        |-- is_atomic
        |-- max_msg_size
        |-- max_rx_timeout_ms
        |-- rx_max_msg
        |-- tx_max_msg
        `-- type

where:

  • errors β€” used to read back timed-out and unexpected replies.
  • message* β€” used to send sync/async commands and read back immediate and delayed responses (if any).
  • notification β€” used to read any notification being emitted by the system (if previously enabled by the user app).
  • reset β€” used to flush the queues of messages (of any kind) still pending to be read; this is useful at test-suite start/stop to get rid of any unread messages from the previous run.

The per-channel entries rooted at /channels are present only on a system where multiple transport channels have been configured.

Those per-channel entries can be used to explicitly choose a specific channel for SCMI bare message injection. This is in contrast with the general entries above, where the selection of the proper channel to use is automatically performed based on the protocol embedded in the injected message and on how the transport is configured on the system. iykyk. πŸ¦‹

Note that other common general entries are available under transport/ to let the user applications properly make up their expectations in terms of timeouts and message characteristics.


πŸ’– message behavior, timeouts, and sequence numbers πŸ’–

Each write to the message* entries causes one command request to be built and sent, while the replies or delayed response are read back from those same entries one message at a time β€” receiving an EOF at each message boundary.

The user application running the test is in charge of handling timeouts on replies and properly choosing SCMI sequence numbers for the outgoing requests. Using the same sequence number is supported, but discouraged. πŸ‘€

Injection of multiple in-flight requests is supported as long as the user application uses properly distinct sequence numbers for concurrent requests and takes care to properly manage all the related issues about concurrency and command/reply pairing. Keep in mind that, anyway, the real level of parallelism attainable in such a scenario is dependent on the characteristics of the underlying transport being used. That’s the tea. πŸ“

Since the SCMI core regular stack is partially used to deliver and collect the messages, late replies arrived after timeouts and any other sort of unexpected message can be identified by the SCMI core as usual, and they will be reported as messages under "errors" for later analysis. Not me being dramatic, that’s just where they show up. πŸ’€


✨ SEE ALSO ✨


source/version: ./drivers/firmware/arm_scmi Β· date: October 2026 Β· page: Theory of operation(9) β€” mwah, go slay your tests bestie πŸ’‹πŸŽ€

πŸ“¦ where this page comes from