ModusToolbox Safety Test Library
Loading...
Searching...
No Matches

General Description

Functions

uint8_t SelfTest_SMPU (const stl_smpu_entry_t *entry)
 Runs the functional self-test for the CPUSS SMPU: temporarily configures a spare SMPU slave struct over the supplied scratch word so the active protection context of the calling core is denied, attempts a denied write, recovers from the resulting BusFault, and verifies both the SysFault source and the data integrity of the scratch word.
bool SelfTest_SMPU_HandleBusFault (uint32_t *stack)
 BusFault dispatch entry for the application's BusFault_Handler trampoline.

Function Documentation

◆ SelfTest_SMPU()

uint8_t SelfTest_SMPU ( const stl_smpu_entry_t * entry)

Runs the functional self-test for the CPUSS SMPU: temporarily configures a spare SMPU slave struct over the supplied scratch word so the active protection context of the calling core is denied, attempts a denied write, recovers from the resulting BusFault, and verifies both the SysFault source and the data integrity of the scratch word.

Parameters
entryPointer to stl_smpu_entry_t describing the scratch word under test, the spare SMPU slave struct, the fault structure, and the expected fault source.
Returns
OK_STATUS - The denied write raised a BusFault with the expected CFSR.BFSR signature (see SelfTest_SMPU_HandleBusFault), the expected CPUSS_MPU_VIO SysFault with DATA0 equal to testAddress, and the scratch word content is unchanged.
ERROR_STATUS - The scratch word did not hold expectedValue on entry, the SMPU configuration failed, the expected fault was not observed, the scratch word content changed during the test, or a fault was already latched when the function was called (captured in faultStruct, or expectedFault pending): the write is then not attempted and the fault is left in faultStruct for the application.
ERROR_INCORRECT_USAGE_STATUS - The active protection context of the calling core is 0, which the SMPU cannot restrict. Nothing is written, including the scratch word.
ERROR_BAD_PARAM - Invalid entry: null pointers, writeValue equal to expectedValue, expectedFault not a valid SysFault source, testAddress not aligned to SMPU_TEST_BLOCK_BYTES, smpuStruct already enabled, allowedPc out of range, or allowedPc equal to the active protection context. Nothing is written in this case.
Note
Before calling this function the application MUST:
  1. Run during system initialization, before the final protection policy is locked.
  2. Install an application-owned BusFault_Handler trampoline that calls SelfTest_SMPU_HandleBusFault() with the exception stack-frame pointer and falls back to the application's normal BusFault policy when the STL declines the fault (see the module note in SMPU (CPUSS shared memory protection STL module)).
  3. Provide a dedicated SMPU_TEST_BLOCK_BYTES scratch block in non-cacheable memory, with its first word primed with stl_smpu_entry_t::expectedValue.
  4. Provide a low, disabled SMPU slave struct and the device/area -specific stl_smpu_entry_t::expectedFault source.
  5. Ensure the calling core runs at a non-zero protection context different from stl_smpu_entry_t::allowedPc.
  6. Handle (read and clear) any fault captured in stl_smpu_entry_t::faultStruct and any pending stl_smpu_entry_t::expectedFault (for example a violation at boot, or one left by an earlier failed call). Otherwise the self-test returns ERROR_STATUS without attempting the write; it does not discard faults it did not cause.
Side effects on entry:
  • The function reinitializes the provided fault structure: CTL, the interrupt mask and MASK0..2 are overwritten so that only stl_smpu_entry_t::expectedFault is captured, with the fault interrupt, reset request, fault_out and trigger outputs disabled. Any prior application configuration of that fault structure is lost.
  • SCB->SHCSR.BUSFAULTENA is forced on for the duration of the call (its prior state is saved and restored on exit) so the denied access reports as a BusFault instead of escalating to HardFault.
  • All SCB->CFSR.BFSR bits (and so BFAR validity) left over from an earlier BusFault are cleared. MMFSR and UFSR are untouched.
  • The SMPU slave struct selected by stl_smpu_entry_t::smpuStruct, which must be disabled, is reprogrammed over the SMPU_TEST_BLOCK_BYTES block at stl_smpu_entry_t::testAddress.
Side effects on exit:
  • The borrowed SMPU slave struct is left disabled; the application is responsible for programming its final operational protection policy. If the disable fails (for example the struct got locked), ERROR_STATUS is returned and the struct may stay enabled, denying access to the scratch block at the calling core's protection context.
  • SCB->SHCSR.BUSFAULTENA is restored to its value on entry.
  • The fault-structure MASK0..2 are left cleared; the application must set up its own fault policy after the self-test returns.
  • The fault-structure STATUS/INTR are cleared only if they hold the test's own violation (stl_smpu_entry_t::expectedFault at stl_smpu_entry_t::testAddress). Any other captured fault is left for the application. If the induced violation was not captured (for example a wrong stl_smpu_entry_t::expectedFault), it stays pending.
  • The application's BusFault_Handler stays installed; after this call returns, SelfTest_SMPU_HandleBusFault() returns false for any further BusFault so the application's normal policy runs.
This is a startup test: call it once during initialization (before an RTOS scheduler starts, if one is used) and before the final operational protection policy is armed. It is blocking (polls up to SMPU_TEST_TIMEOUT_US microseconds), is not reentrant, and must not be called from an ISR or any other exception handler.
Interrupts are not masked during the test. An interrupt can never cause a false OK_STATUS. An interrupt that accesses the scratch block while the struct is enabled, or reprograms the borrowed struct or the fault structure, causes ERROR_STATUS or a BusFault handled by the application's policy. BusFault must not be masked when the function is called: no PRIMASK or FAULTMASK (for example inside __disable_irq() or Cy_SysLib_EnterCriticalSection()) and no BASEPRI at or above the BusFault priority. These conditions are not checked at runtime. If BusFault is masked, a precise fault escalates to HardFault. An imprecise fault stays pending: the function returns ERROR_STATUS and the pending BusFault is taken later, outside the test window, by the application's BusFault policy. Neither case can produce a false OK_STATUS.
Any other BusFault raised while this function runs is not consumed by SelfTest_SMPU_HandleBusFault() and reaches the application's BusFault policy.

◆ SelfTest_SMPU_HandleBusFault()

bool SelfTest_SMPU_HandleBusFault ( uint32_t * stack)

BusFault dispatch entry for the application's BusFault_Handler trampoline.

Recovers the deliberate denied write driven by SelfTest_SMPU (rewrites the stacked PC to the STL resume point) and returns true.

A fault is accepted as the deliberate one only if all of the following are true:

  • SelfTest_SMPU is inside its test window,
  • the stacked PC lies within the STL write helper (from the denied STR up to the resume point), and
  • CFSR.BFSR is exactly IMPRECISERR, or exactly PRECISERR | BFARVALID with the stacked PC at the STR and BFAR equal to stl_smpu_entry_t::testAddress.

Any other BusFault, inside or outside the test window, is left untouched and false is returned so the application's normal policy handles it.

Parameters
stackPointer to the exception stack frame (r0, r1, r2, r3, r12, lr, pc, xpsr) that was active when the fault occurred, selected from MSP or PSP by the application trampoline. NULL is rejected (returns false).
Returns
true - Fault was the STL's deliberate denied write; stack[6] has been rewritten to resume execution after the store and the accepted CFSR.BFSR bits have been cleared (other CFSR bits are preserved). The application trampoline must return normally so the exception return uses the (unchanged) EXC_RETURN value in LR.
false - stack is NULL, or the fault does not match the criteria above. stack, SCB->CFSR, SCB->BFAR and the STL state are untouched. The application trampoline must invoke its own BusFault policy.
Note
This function is safe to call from the BusFault exception context. It must not be called from ordinary code and must not be treated as a general test API.