User Trap Handling in PXROS-HR: Application Note

Terms & Abbreviations

CSA

Context Save Area

TIN

Trap Identification Number

MPE

Memory Protection Error

DSTR

Data Synchronous Trap Register

DEADD

Data Error Address Register

DATR

Data Asynchronous Trap Register

Introduction

The document applies to PXROS-HR for TriCore version 8.2.0.

This document describes how to create and configure trap handler functions and install these trap handlers to PXROS-HR.

The application note shows how to deal with possible traps by using trap handlers and recognizing which error caused a trap. In the appendix, we also provide code snippets enabling the trigger of specific traps by software to enable testing of these traps in the application.

This note describes how to recognize types of errors that occurred, how to solve them, in which context a trap handler runs, and which functions can be called.

Aurix trap system overview

The TriCore architecture specifies eight general classes for traps. Each class has its own trap handler, accessed through a trap vector of 32 bytes per entry, indexed by the hardware-defined trap class number. Detailed information can be found in [1].

Traps can be further classified as synchronous or asynchronous, and as hardware or software generated.

Synchronous traps

Synchronous traps are associated with the execution or attempted execution of specific instructions, or with an attempt to access a virtual address that requires the intervention of the memory-management system. The instruction causing the trap is known precisely. The trap is taken immediately and serviced before execution can proceed beyond that instruction.

Asynchronous traps

Asynchronous traps are similar to interrupts, in that they are associated with hardware conditions detected externally and signaled back to the core. Some result indirectly from instructions that have been previously executed, but the direct association with those instructions has been lost. Others, such as the Non-Maskable Interrupt (NMI), are external events. The difference between an asynchronous trap and an interrupt is that asynchronous traps are routed via the trap vector instead of the interrupt vector. They can not be masked and they do not change the current CPU interrupt priority number.

Hardware traps

Hardware traps are generated in response to exception conditions detected by the hardware. In most, but not all cases, the exception conditions are associated with the attempted execution of a particular instruction.

Examples are the illegal instruction trap, memory protection traps and data memory misalignment traps. In the case of the MMU traps (trap class 0), the exception condition is either the failure to find a TLB (Translation Lookaside Buffer) entry for the virtual page referenced by an instruction (VAF trap), or an access violation for that page (VAP trap).

Software traps

Software traps are generated as an intentional result of executing a system call or an assertion instruction. The supported assertion instructions are TRAPV (Trap on overflow) and TRAPSV (Trap on sticky overflow). System calls are generated by the SYSCALL instruction.

Unrecoverable traps

An unrecoverable trap is one from which software can not recover; i.e. the task that raised the trap can not be simply restarted. In the TriCore architecture, FCU (a fatal context trap) is an unrecoverable error. See “FCU - Free Context List Underflow (TIN 4)” on Page 9 for more information.

Trap descriptions

Details can be found in Infineon user manual [1].

In the following tables:

  • TIN = Trap Identification Number

  • Synch. = Synchronous / Asynch. = Asynchronous

  • HW = Hardware / SW = Software.

MMU traps (Trap Class 0)

For those implementations that include a Memory Management Unit (MMU), Trap class 0 is reserved for MMU traps. There are two traps within this class, VAF and VAP.

TIN Name Synch. / Asynch. HW / SW Definition

0

VAF

Synch.

HW

Virtual Address Fill

1

VAP

Synch.

HW

Virtual Address Protection

Internal protection traps (Trap Class 1)

Trap class 1 is for traps related to the internal protection system. The memory protection traps in this class, MPR, MPW, and MPX, are for the range-based protection system and are independent of the page-based VAP protection trap of trap class 0. All memory protection traps (MPR, MPW, MPX, MPP, and MPN), are based on the virtual addresses that undergo direct translation.

TIN Name Synch. / Asynch. HW / SW Definition

1

PRIV

Synch.

HW

Privileged Instruction

2

MPR

Synch.

HW

Memory Protection Read

3

MPW

Synch.

HW

Memory Protection Write

4

MPX

Synch.

HW

Memory Protection Execute

5

MPP

Synch.

HW

Memory Protection Peripheral Access

6

MPN

Synch.

HW

Memory Protection Null Address

7

GRWP

Synch.

HW

Global Register Write Protection

Instruction errors (Trap Class 2)

Trap class 2 is for signalling various types of instruction errors. Instruction errors include errors in the instruction opcode, in the instruction operand encodings, or for memory accesses, in the operand address.

TIN Name Synch. / Asynch. HW / SW Definition

1

IOPC

Synch.

HW

Illegal Opcode

2

UOPC

Synch.

HW

Unimplemented Opcode

3

OPD

Synch.

HW

Invalid Operand specification

4

ALN

Synch.

HW

Data Address Alignment

5

MEM

Synch.

HW

Invalid Local Memory Address

Context management (Trap Class 3)

Trap class 3 is for exception conditions detected by the context management subsystem, in the course of performing (or attempting to perform) context save and restore operations connected to function calls, interrupts, traps, and returns.

TIN Name Synch. / Asynch. HW / SW Definition

1

FCD

Synch.

HW

Free Context List Depletion (FCX = LCX)

2

CDO

Synch.

HW

Call Depth Overflow

3

CDU

Synch.

HW

Call Depth Underflow

4

FCU

Synch.

HW

Free Context List Underflow (FCX = 0)

5

CSU

Synch.

HW

Call Stack Underflow (PCX = 0)

6

CTYP

Synch.

HW

Context Type (PCXI.UL wrong)

7

NEST

Synch.

HW

Nesting Error: RFE with non-zero call depth

System bus and peripheral errors (Trap Class 4)

Trap class 4 is for system bus and peripheral errors.

TIN Name Synch. / Asynch. HW / SW Definition

1

PSE

Synch.

HW

Program Fetch Synchronous Error

2

DSE

Synch.

HW

Data Access Synchronous Error

3

DAE

Asynch.

HW

Data Access Asynchronous Error

4

CAE

Asynch.

HW

Coprocessor Trap Asynchronous Error

5

PIE

Synch.

HW

Program Memory Integrity Error

6

DIE

Asynch.

HW

Data Memory Integrity Error

7

TAE

Asynch.

HW

Temporal Asynchronous Error

Assertion traps (Trap Class 5)

Trap class 5 is for assertation traps.

TIN Name Synch. / Asynch. HW / SW Definition

1

OWF

Synch.

SW

Arithmetic Overflow

2

SOVF

Synch.

SW

Sticky Arithmetic Overflow

System call (Trap Class 6)

Trap class 6 is for system calls.

TIN Name Synch. / Asynch. HW / SW Definition

 — 

SYS

Synch.

SW

System Call

Non-maskable interrupt (Trap Class 7)

Trap class 7 is for non-maskable interrupt.

TIN Name Synch. / Asynch. HW / SW Definition

0

NMI

Asynch.

HW

Non-Maskable interrupt

PXROS-HR trap handling

The PXROS-HR kernel, being an interrupt lock-free kernel, does not provide Enable/Disable interrupts API. Moreover, it re-enables the core interrupts in its exception entry (trap prologue) that might lead to unexpected side-effects when Enable/Disable interrupts are implemented on the application level.

The PXROS-HR trap handling needs at least 3 free CSAs for:

  1. Any trap (except FCU) stores an upper context (done by the TriCore)

  2. The trap prologue saves the lower context

  3. The call of the installed user-defined trap handler saves another upper context

The PXROS-HR default trap handler is an internal function that is called in all trap class handlers except SYSCALLs. The default trap handling routine — PxTrapAbort() — is called when no user-trap handler is installed.

PXROS-HR trap vector table

PXROS-HR provides a PXROS-HR trap vector table with 8 trap entries, one for each class. The table is initialized with the default trap handling routine and contains user-defined trap handlers once they are installed. Registering two different user trap handlers for one class on one core is impossible. Items in the trap handler table are overridable; only the last handler set for a specific class is used. However, it is possible to map one handler to several classes and decide in runtime which class was called by trap number, which is passed as an argument to a user trap handler.

Users can define and register up to 7 user trap handlers because the kernel reserves number 6 for SYSCALLs.

The following table shows for which trap classes the default PXROS-HR trap handling can be replaced with the user-defined trap handlers.

Tab. 1. Replaceability by a user trap handler
Trap class number Trap class name Replacable by a user trap handler

0

MMU Traps

Yes

1

Internal Protection Traps

Partly

2

Instruction Errors

Yes

3

Context Management

Yes*

4

System Bus and Peripheral Errors

Yes

5

Assertion Traps

Yes

6

System Call

No

7

Non-Maskable Interrupt

Yes

* For Free Context List Underflow (FCU) trap, the user-defined trap handler is not called

Trap execution sequence

There are several steps from the trap occurrence to the user-defined trap handler execution. The following PXROS-HR components are involved in PXROS-HR trap handling, ordered as they are executed in sequence (details are provided below):

  • Trap prologue — 32 bytes of code per entry (class) ending with a jump to a class handler

  • Class handler — 8 trap classes, one class handler per class

  • Special internal PXROS-HR handlers — memory access resolution for MPU traps

  • PXROS-HR default trap handler — preparation of the context for a user-defined trap handler

  • User-defined trap handler — implemented by the user

  • PXROS-HR default trap handling routine — PxTrapAbort()

The trap prologue saves the lower context, reads DSTR and DEADD registers, clears DSTR, enables interrupts and jumps to a PXROS-HR class handler. Only entry number 6, reserved by the kernel for SYSCALLs, has a different prologue.

There are some differences in the PXROS-HR class handler implementation for some specific classes — more detailed at Special classes. Each PXROS-HR class handler (except SYSCALLs) contains a call to the PXROS-HR default trap handler.

If the trap occurs when ICR.CCPN is 0, the PXROS-HR default trap handler sets ICR.CCPN to 1. By setting ICR.CCPN to 1, the PXROS kernel mode is entered, scheduling is disabled and all trap handlers are executed in handler mode. At the end of executing the PXROS-HR default trap handler, it is decided whether to continue with a user-defined trap handler if it was previously registered or the default trap handling routine.

  • A user trap handler was registered

    If the installer task is available, it is switched to its context. Otherwise, the trap handler is executed in kernel context. Then, a registered user trap handler is called. Trapped context is restored if the installer task exists. If the user trap handler successfully handled a trap, OS executes a return from the trap and leaves the supervisor mode. If the user trap handler cannot solve the trap (returned false), PxTrapAbort() is the default trap handling routine.

  • A user trap handler was not registered

    PxTrapAbort() is called as the trap handling routine.

A simplified image showing the execution sequence is available below.

class1 execution sequence
Fig. 1. Trap execution sequence — example for class 1 (Internal Protection Trap)

Returning from trap

For a synchronous trap, the return address is the PC of the instruction that caused the trap. On a SYS trap triggered by the SYSCALL instruction, the return address points to the instruction immediately following SYSCALL. For an asynchronous trap, the return address is that of the instruction that would have been executed next if the asynchronous trap had not been taken. The return address for an interrupt follows the same rule.

Special classes

Internal protection (class 1)

There is an internal PXROS-HR MPU trap handler that is called first. This handler tries to solve the access problem. If it fails, the trap is not handled, and a user-trap handler is called if it was installed.

The internal PXROS-HR MPU trap handler that first tries to resolve the memory access does not change the ICR.CCPN value and therefore runs on task level. However, if the kernel does not resolve the memory access, the default PXROS-HR trap handler is called.

This class needs at least 3 free CSAs when the PXROS-HR tracing mechanism is not used. The trace configuration may influence how many CSAs are needed.

Context management (class 3)

In the case of FCU, a user-defined trap handler is not called because there are no free CSAs. FCU traps will result in an endless trap recursion because saving the lower context will always trigger the next FCU trap. Therefore, it is recommended that the LCX is set up properly and the FCD trap is handled.

An interrupt can occur while handling the FCD trap, resulting in spending another CSAs.

System call (class 6)

The SYSCALL instruction generates a system call trap, providing a secure mechanism for the user mode application code to request Supervisor mode services. If a handler is installed for SYSCALL it is never used — there is no calling of a user trap handler in this class.

Initial state upon a trap

Initial state upon a HW trap

Detailed information can be found in [1].

The initial state when a HW trap occurs is defined as follows:

  • The upper context is saved.

  • The return address in A[11] is updated.

  • The TIN is loaded into D[15].

  • The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP) when the processor was not previously using the interrupt stack (in case of PSW.IS = 0). The stack pointer bit is set for using the interrupt stack: PSW.IS = 1.

  • The I/O mode is set to Supervisor mode, which means all permissions are enabled: PSW.IO = 10B.

  • The current Protection Register Set is set to 0: PSW.PRS = 000B.

  • The Call Depth Counter (CDC) is cleared, and the call depth limit is set for 64: PSW.CDC = 0000000B.

  • Call Depth Counter is enabled, PSW.CDE = 1.

  • PSW Safety bit is set to value defined in the SYSCON register. PSW.S = SYSCON.TS.

  • Write permission to global registers A[0], A[1], A[8], A[9] is disabled: PSW.GW = 0.

  • The interrupt system is globally disabled: ICR.IE = 0. The 'old' ICR.IE and ICR.CCPN are saved into PCXI.PIE and PCXI.PCPN respectively. ICR.CCPN remains unchanged.

  • The trap vector table is accessed to fetch the first instruction of the trap handler.

Although traps leave the ICR.CCPN unchanged,their handlers still begin execution with interrupts disabled. They can therefore perform critical initial operations without interruptions, until they specifically re-enable interrupts.

For the non-recoverable FCU trap, the initial state is different. The upper context cannot be saved. Only the following states are guaranteed:

  • The TIN is loaded into D[15].

  • The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP) when the processor was not previously using the interrupt stack (in case of PSW.IS == 0).

  • The I/O mode is set to Supervisor mode (all permissions are enabled: PSW.IO = 10B).

  • The current Protection Register Set is set to 0: PSW.PRS = 000B.

  • PSW Safety bit is set to value defined in the SYSCON register: PSW.S = SYSCON.TS.

  • The interrupt system is globally disabled: ICR.IE = 0. ICR.CCPN remains unchanged.

  • The trap vector table is accessed to fetch the first instruction of the FCU trap handler.

Initial state after the PXROS-HR trap prologue

A few things differ from a default HW trap when using PXROS-HR. The PXROS-HR prologue takes care of:

  1. The lower context is saved

  2. DSTR and DEADD registers are read

  3. DSTR is cleared

  4. Interrupts are enabled

For Asynchronous traps, PXROS-HR does not read the DATR register, and the user always has to read the DATR register to get the reason of the trap.

Initial state upon a user trap handler

Initial state after executing the default PXROS-HR trap handler — base state for a user trap handler:

  • Interrupts are enabled

  • If ICR.CCPN was 0, set to 1

  • Status register values from the HW trap’s initial state are no longer valid. Therefore, the six arguments of the user trap handler are used instead. These are passed to a user trap handler to identify what happened (more at User trap handler definition).

  • Interrupt Stack Pointer (ISP) is used

  • I/O mode is set to Supervisor

  • The current Protection Register Set is set to 3 (combines the address spaces of the kernel and the task that installed the user trap handler)

  • The Call Depth Counter (CDC) is set to 1

The rest remains the same as described above.

Trap handler context

A trap handler runs with supervisor privileges within the MPU context that combines the kernel and the task that installed the trap (trap installer task). Union of Protection Set 1 (kernel) and Protection Set 2 (task) is used to merge MPU settings of a trap installer task and kernel. If the installer task no longer exists, the trap is executed only in the kernel context. If there is a need to access the task context of a task that caused a trap, a user must ensure correct access rights. Otherwise, it may cause another MPU trap.

Context Save Area (CSA) structures are linked, and users can use them to get information about the execution state when a trap occurs. The csa argument passed to the function is the lower context of the last processed function. The upper context was previously stored by hardware, and accessing it through the lower context is possible. CSAs can be iterated so the user can back-track an execution flow of the application.

There is a flag for recognition if the pointer stored in PCXI (Previous Context Information — is part of both the lower and the upper CSA structure) points to lower or upper CSA. This flag bit is PCXI.UL.

Code 1. Decision whether the PCXI points to lower or upper CSA
if (csa->lower.PCXI.UL)
    /* PCXI points to upper CSA */
else
    /* PCXI points to lower CSA */
Code 2. Example how to get upper CSA from lower CSA by using 'CSA2PTR' function defined in "pxdef.h"
/* =========================== pxdef.h definition =========================== */

/* CSA block */
typedef union
{
    TC_CSA_UPPER_T upper;   /* < upper CSA block */
    TC_CSA_LOWER_T lower;   /* < lower CSA block */
} TC_CSA_t;

/******************************************************************************/
//! get the absolute pointer to the csa
static inline __attribute__((always_inline)) TC_CSA_t *CSA2PTR(PxPCXI_t csa)
{
    TC_CSA_t *pcsa;
    __asm__ volatile (
            "sha.h  %0, %1, 12\n\t" // shift segment into bit 28-31
            "insert %0, %0, %1, 6,16" // move offset into bits 0-22
            : "=&d" (pcsa) : "d" (csa) );
    return pcsa;
}

/* ======================== trap handler definition ======================== */

/* Class 1 (MPU) trap handler */
PxBool_t Trap_Hdn_01(..., TC_CSA_t *csa)
{
    TC_CSA_t *csa_upper = CSA2PTR(csa->lower.PCXI);

    ...

Known limitations

When a trap that should update the DEADD register occurs while handling an asynchronous trap, the DATR is not cleared, and the DEADD is not updated. This results in getting the wrong DEADD as an argument in the newest user-defined trap handler.

"The register is only set whenever a trap is detected and either the DATR or DSTR registers have no bits already set." [3]

User trap handler definition

It is necessary to implement a handler function fulfilling this prototype:

Code 3. Handler prototype definition
PxBool_t(* traphandler)(PxTrapTin_t trapTin, PxUInt_t hnd_arg, PxUInt_t runtaskId,
                        PxUInt_t dstr, PxUInt_t *deadd, TC_CSA_t *csa);

Parameters:

  • trapTin — trap class number & TIN — to identify which error occurred according to the Trap descriptions tables

  • hnd_arg — user-defined argument — argument is passed during handler installation

  • runtaskId — task ID of the task that caused the trap

  • dstr — contents of DSTR — content of this register is implementation-specific, additional information is provided in section 5.3.6.4 of [2]

  • deadd — contents of DEADD — content of this register is implementation-specific, additional information is provided in section 5.3.6.4 of [2]

  • csa — pointer to the saved CSA — only the lower part of architectural registers in the state they were right before entering trap handling (upper part can be accessed via the link of PCXI value as shown in Decision whether the PCXI points to lower or upper CSA)

Description:

A trap handler is a function where decisions about the next steps are made according to the error. Traps are divided into classes that describe similar types of errors, and each specific error has an assigned TIN.

A trap handler should return true if the handler can successfully handle the error, otherwise false, which means PxTrapAbort() is called as the default trap handling routine.

Code 4. Example of a trap handler prototype
PxBool_t Trap_Hnd_04(PxTrapTin_t trapTin, PxUInt_t hnd_arg, PxUInt_t runtaskId,
                     PxUInt_t dstr, PxUInt_t *deadd, TC_CSA_t *csa);

User trap handler installation

A trap handler runs with supervisor privileges within the kernel + trap installer task context. Only one task can register the handler! In this case, the user should keep in mind that when a different task (than the installer task) causes a trap, the memory protection unit will not be set for the violating task.

The PxTrapInstallHandler() function is used for trap handler installation. The task that installs trap handlers must have these access rights: PXACCESS_HANDLERS and PXACCESS_INSTALL_HANDLERS.

PxError_t PxTrapInstallHandler(PxUInt_t trapno,
                               PxBool_t(* traphandler)(PxTrapTin_t, PxUInt_t, PxUInt_t,
                                                       PxUInt_t, PxUInt_t *,TC_CSA_t *),
                               PxUInt_t arg);

Parameters:

Code 5. Example installation of a class 1 handler in Init task
PxBool_t Trap_Hnd_01(PxTrapTin_t trapTin, PxUInt_t hnd_arg, PxUInt_t runtaskId,
                     PxUInt_t dstr, PxUInt_t *deadd, TC_CSA_t *csa)
{
    /* implementation */
}

void InitTask_Func(PxTask_t myID, PxMbx_t myMailbox, PxEvents_t myActivationEvents)
{
    ...

    PxError_t err;
    err = PxTrapInstallHandler(1, Trap_Hnd_01, 0);  /* No user argument passed */
    if (err != PXERR_NOERROR)
        PxPanic();

Analyzing trap root cause

TINs (Trap Identification Number) are used for detailed analysis of the trap root cause in aid of data in DSTR, DATR, and DEADD registers. Traps are divided into 8 classes, each with similar types of traps. Each class has a further division to identify what happened in detail. This division is based on specific TINs. The corresponding description is in chapter Trap descriptions.

DMI Trap Generation (DMI = Data Memory Interface) can be found in Aurix target specification chapter 5.3.6.4.4 [2]. Register description of DSTR, DATR, and DEADD in the same chapter below. These three registers are used to aid with the localization of faults. DSTR meaning is to inform about which synchronous error caused a trap. DATR meaning is to inform about which asynchronous error caused a trap. And the value of DEADD is an address that tells detailed information about the fault. The DEADD register contents are only valid when either the DATR or DSTR register is non-zero.

For Asynchronous traps, PXROS-HR does not read the DATR register, and the user always has to read the DATR register to get the reason of the trap.

For example, if a task tries to write at address 0x8 and its memory protection unit is not set for that address, this write (store instruction) causes a trap. DSTR is updated, and the MPE bit is set. In the DEADD register is the value of the address where the task tried to write (0x8).

Tab. 2. Information contained in 'DSTR' register
Bit Bit Name Description

SRE

Scratch Range Error

Data access to data scratch memory region outside of physically implemented memory

LBE

Load Bus Error

Data load from bus causing error

CRE

Cache Refill Error

Bus error during cache refill

DTME

DTAG MSIST Error

Access to memory mapped DTAG range outside of physically implemented memory

LOE

Load Overlay Error

Load to invalid overlay address

SDE

Segment Difference Error

Load or store access where base address is in different segment to access address

SCE

Segment Crossing Error

Load or store access across segment boundary

CAC

CSFR Access Error

Load or store to local CSFR space

MPE

Memory Protection Error

Data access violating memory protection.

CLE

Context Location Error

Context operation to invalid location

ALN

Alignment Error

Data access causing alignment error

Tab. 3. Information contained in 'DATR' register
Bit Bit Name

SBE

Store Bus Error

CWE

Cache Writeback Error

CFE

Cache Flush Error

SOE

Store Overlay Error

Supported PXROS-HR API in trap handler

PXROS-HR trap handler is a handler, meaning only PXROS-HR API functions with the suffix _Hnd can be called inside the handler.

Name Definition

PxDelaySched_Hnd

Schedule a delay job

PxMsgGetData_Hnd

Get data area of a message

PxMsgGetMetadata_Hnd

Get the metadata of the message

PxMsgRelease_Hnd

Release a message object

PxMsgSend_Hnd

Send normal message

PxMsgSend_PrioHnd

Send prioritized message

PxMsgSetMetadata_Hnd

Set the metadata for the message

PxPeStart_Hnd

Start periodic events

PxPeStop_Hnd

Stop periodic events

PxRegisterRead_Hnd

Read a value from a SFR register

PxRegisterSetMask_Hnd

Write all bits of value to a SFR register according to the mask

PxRegisterWrite_Hnd

Write a value to a SFR register

PxTaskSignalEvents_Hnd

Signal events to a task

PxTaskSuspend_Hnd

Prevent a task from being scheduled

PxTickDefine_Hnd

Increment the PXROS-HR tick

PxToStart_Hnd

Start timeout

PxToStop_Hnd

Stop timeout

Stack overflow recognition

There is no exact way how to recognize stack overflow from just a regular MPU error.

One idea can be to recognize a stack overflow as an access that is close to the stack boundary. There may be a higher probability of stack overflow when the error address stored in DEADD is close to the stack boundary, but it is not guaranteed at all. The problem comes with defining "close". It can be a low number when a variable that is being accessed is right next to the stack boundary and quite a high number when the accessed variable is a part of a complex structure.

Example implementation of PXROS-HR trap handler

Example implementation of a trap handler for class 1 traps. This handler is designed to be used on multiple cores but must be installed individually on each core.

#define TC_CORE_ID          0xFE1C  /* "Core Identification" */
#define TC_CORE_ID_MASK     0x7     /* "Core Identification field mask" */

PxBool_t Trap_Hnd_01(PxTrapTin_t trapTin, PxUInt_t hnd_arg, PxUInt_t runtaskId,
                     PxUInt_t dstr, PxUInt_t *deadd, TC_CSA_t *csa);
{
    /* Get core ID from core register value 6 corresponds to core 5 (Errata) */
    PxUInt_t coreId = __MFCR(TC_CORE_ID) & TC_CORE_ID_MASK;
    if (coreId == 6)
        coreId--;

    PxTask_t task_id = PxTaskIdSet(runtaskId);
    TC_CSA_t *csa_upper;
    csa_upper = CSA2PTR(csa->lower.PCXI);

    if (PxTaskIdIsValid(task_id))
    {
        /* Different solution on different cores */
        switch (coreId)
        {
        case 0: /* Core 0 */
            switch (trapTin.t.tin)
            {
            case PRIV: /* TIN 1 - Privileged Instruction */
                /* Code to handle PRIV */
                return true;
            case MPR: /* TIN 2 - Memory Protection Read */
                /* Code to handle MPR */
                return true;
            case MPW: /* TIN 3 - Memory Protection Write */
                /* Code to handle MPW */
                return true;
            }
            /* Other TINs not handled */
            break;

        case 1: /* Core 1 */
            /* Code to handle all TINs */
            return true;

        default: /* Other cores */
            /* Trap not handled on other cores */
            return false;
        }
    }
    return false;
}

Appendix A: Generation of Traps

It is possible to generate a trap violently. All MPU traps generation is listed below. There also is a way to generate a trap from classes 3, 4.

Internal Protection Traps (Trap Class 1)

For violent trap generation, the MPU must not be set for areas where the instruction should cause a trap.

Code 6. Privileged Instruction (TIN 1)
__MTCR(0xC010, 0xFF);
Code 7. Memory Protection Read (TIN 2)
trapCnt = *(unsigned int *) 0x8;
Code 8. Memory Protection Write (TIN 3)
*(PxUInt_t *) 0x8 = 0x20;
Code 9. Memory Protection Execute (TIN 4)
int (*bad_instruction)(void) = (void *)0x81000001;
bad_instruction();
Code 10. Memory Protection Peripheral Access (TIN 5)
trapCnt = SCU_CCUCON0.U;
Code 11. Memory Protection Null Address (TIN 6)
trapCnt = *(unsigned int *) 0x0;
Code 12. Global Register Write Protection (TIN 7)
__asm__ volatile ("movh.a %a0, 0x8000");

System Bus and Peripheral Error (Trap class 3)

Code 13. Free Context List Underflow (TIN 4)
void csa_underflow()
{
    csa_underflow();
}

void InitTask_Func(PxTask_t myID, PxMbx_t myMailbox, PxEvents_t myActivationEvents)
{
    ...

    csa_underflow();

This (FCU) will cause an unrecoverable error. Stack size must be sufficient not to cause the MPU error (stack overflow) first.

System Bus and Peripheral Error (Trap class 4)

Code 14. Program Fetch Synchronous Error (TIN 1)
int (*bad_instruction)(void) = (void *)0xE0000000;
bad_instruction();

Document References

[1] "TriCore TC1.6.2 Core Architecture Manual, Volume 1" , Infineon, 2020

[2] "AURIX TC3xx Target Spec Part 1 of 2" , Infineon, 2020

[3] "AURIX TC3xx User Manual Part-1" , Infineon, 2021

Document history

Version Date Changes to the previous version

1.0

August 2021

Initial version

2.0

November 2023

Document structure and content are substantially re-wised and enhanced to provide better clarity for the reader.

Disclaimer

 
 
 

Please Read Carefully:

This document contains descriptions for copyrighted products that are not explicitly indicated as such. The absence of the TM symbol does not infer that a product is not protected. Additionally, registered patents and trademarks are similarly not expressly indicated in this document.

The information in this document has been carefully checked and is believed to be entirely reliable. However, HighTec EDV-Systeme GmbH assumes no responsibility for any inaccuracies. HighTec EDV-Systeme GmbH neither gives any guarantee nor accepts any liability whatsoever for consequential damages resulting from the use of this document or its associated product. HighTec EDV-Systeme GmbH reserves the right to alter the information contained herein without prior notification and accepts no responsibility for any damages that might result.

HighTec EDV-Systeme hereby disclaims any and all warranties and liabilities of any kind, including without limitation, warranties of non-infringement of intellectual property rights of any third party.

Rights - including those of translation, reprint, broadcast, photomechanical or similar reproduction and storage or processing in computer systems, in whole or in part - are reserved. No reproduction may occur without the express written consent from HighTec EDV-Systeme GmbH.

Copyright © 2023 HighTec EDV-Systeme GmbH, D-66113 Saarbrucken.