How-To: LM32 Soft-CPU - Simple Stack Check

Introduction

This how-to demonstrates how a simple check for possible stack violation has been implemented.

Principle

Stack is located at the end of the (usable) memory area. In case a program uses too much RAM, a program will write into the stack of its own CPU making program execution unpredictable. Advanced tools for detecting such indicidents exist, but use too much resources. The following simple method has been implemented.

  • a 'magic word' is written to a register located at the very end of the lm32 (user) RAM
  • with each iteration of the main loop, the content of the register is checked
  • stack violation is assumed, if the register no longer contains the magic word
  • in the simplest case text output is written to the text console (via 'assert'); use 'eb-console' for investigating ...
  • instead, relevant information is written to the memory space of the 'firmware ID'. The firmware ID can be investigated

How-To Details

firmware ID
The firmware ID now contains an additional field
[user@scuxl1234 ~]# eb-info -w dev/wbm0
...
Detecting Firmwares ...

Found 1 RAMs, 1 holding a Firmware ID


********************
* RAM @ 0x04060000 *
********************
UserLM32
Stack Status:  okok              // <-- watch this; the ugly formatting is on purpose (32bit alignment)
Project     : ...
...

additional code (snippet)
the code must be incorporated into your own lm32 program
...
// includes specific for bel_projects
#include <stack.h>
...

void main(void) {
...
  uint32_t *buildID;
...
  buildID           = (uint32_t *)(INT_BASE_ADR + BUILDID_OFFS);
...
  while (1) {
    check_stack_fwid(buildID);  // replace with 'check_stack()' in case you prefer spamming your White Rabbit console
    ...
  } // while
...
} // main

detection, 1st method
[user@scuxl1234 ~]# eb-info -w dev/wbm0
...
UserLM32
Stack Status:                                // <-- no status; firmware is running without 'check stack'
...

  OR

[user@scuxl1234 ~]# eb-info -w dev/wbm0
...
UserLM32
Stack Status:  okok                          // <-- stack ok
...

  OR

[user@scuxl1234 ~]# eb-info -w dev/wbm0
...
UserLM32
Stack Status:  Stack overflow! (0xcafebabe, 0x00027dabe1f41778) // <-- stack corrupted; actual register value and TAI displayed within brackets
...

detection, 2nd method
Assuming the address 0x4060000 is the start of your 'LM32-RAM-User'. Reading from offset 0x118 will do the trick:
[user@scuxl1234 ~]# eb-read dev/wbm0 0x04060118/4
20202020                                     // <-- no status; firmware is running without 'check stack'

  OR

[user@scuxl1234 ~]# eb-read dev/wbm0 0x04060118/4
6f6b6f6b                                     // <-- stack ok

  OR
[user@scuxl1234 ~]# eb-read dev/wbm0 0x04060118/4
< any value other than 6f6b6f6b, 20202020 >  // <-- stack corrupted

In principle this 2nd method could be used to periodically check for a corrupted stack from a userland application.

How-To Implementation

The following files have been changed
  • modules/lm32-include/build_lm32.mk : included additional field
  • modules/lm32-include/stack.h : prototype for new routine 'check_stack_fwid'
  • modules/lm32-include/stack-check.c: implementation of new routine 'check_stack_fwid'
  • see commit ff65bcba0f6f581a28f20bce2bd543f2c222e1d4 (bel_projects @ github)

-- DietrichBeck - 04 Jun 2019
Topic revision: r4 - 04 Jul 2019, DietrichBeck
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback