A DIF is a “Device Interface Function”. DIFs are low-level routines for accessing the hardware functionality directly, and are agnostic to the particular environment or context they are called from. The intention is that DIFs can be used during design verification, and during early silicon verification, and by the high-level driver software in production firmware.
This subtree provides headers and libraries known collectively as the DIF libraries.
There is one DIF library per hardware IP, and each one contains the DIFs required to actuate all of the specification-required functionality of the hardware they are written for.
DIFs are very low-level software, so they have a more rigorous coding style than other parts of the codebase.
DIFs should follow the OpenTitan C/C++ style guide where it does not contradict with the guidelines below.
The guidelines below apply to writing DIFs, and code should be written in a similar style to the existing DIF libraries in this directory.
sw/device/lib/base
directory:sw/device/lib/base/mmio.h
sw/device/lib/base/memory.h
The following rules must be followed by public DIF functions (those declared in the DIF library‘s header file). Internal DIF functions (those declared static
and not declared in the DIF library’s header file) should follow these rules but there are some relaxations of these rules for them described at the end.
DIF declarations must match their definitions exactly.
const
or volatile
(cv-qualified) in DIF signatures.DIFs must use enum return codes rather than booleans for reporting errors. If a DIF can either error or instead produce a value, it should return an enum return code, and use an out-parameter for returning the produced value.
void
.DIFs must check their arguments against preconditions using “guard statements”. A guard statement is a simple if statement at the start of a function which only returns an error code if the preconditions are not met. Guard statements must cover the following checks:
mmio_region_t
are not pointers, and cannot meaningfully be checked for non-nullness.Switch statements in DIFs must always have a default case, including when switching on an enum value (an “enum switch”).
case
for enum variants that are unreachable due to a guard statement.DIFs must use sw/device/lib/base/mmio.h
for accessing memory-mapped hardware. DIFs must not use sw/device/lib/base/memory.h
for accessing memory-mapped hardware.
Internal DIF functions, which are not intended to be part of a public DIF library interface, must not be declared in the DIF library header, and must be marked static
.
static
DIF functions should not be marked static inline
.