summaryrefslogtreecommitdiff
path: root/ports/xtensa/xcc/src/tx_thread_stack_build.S
blob: a52fc35e2f1ea7eb19ef9cf03d392f95d2bc8893 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/***************************************************************************
 * Copyright (c) 2024 Microsoft Corporation
 * Copyright (c) 2026-present Eclipse ThreadX contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * SPDX-License-Identifier: MIT
 **************************************************************************/

/**************************************************************************/
/*   Copyright (c) Cadence Design Systems, Inc.                           */
/*                                                                        */
/* Permission is hereby granted, free of charge, to any person obtaining  */
/* a copy of this software and associated documentation files (the        */
/* "Software"), to deal in the Software without restriction, including    */
/* without limitation the rights to use, copy, modify, merge, publish,    */
/* distribute, sublicense, and/or sell copies of the Software, and to     */
/* permit persons to whom the Software is furnished to do so, subject to  */
/* the following conditions:                                              */
/*                                                                        */
/* The above copyright notice and this permission notice shall be         */
/* included in all copies or substantial portions of the Software.        */
/*                                                                        */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
/**************************************************************************/

/**************************************************************************/
/**************************************************************************/
/**                                                                       */
/** ThreadX Component                                                     */
/**                                                                       */
/**   Thread                                                              */
/**                                                                       */
/**************************************************************************/
/**************************************************************************/


#include "xtensa_rtos.h"
#include "tx_api_asm.h"

    .text

/**************************************************************************/
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function builds a stack frame on the supplied thread's stack.  */
/*    The stack frame looks like an interrupt frame or a solicited frame  */
/*    depending on the exception architecture of the target hardware.     */
/*                                                                        */
/**************************************************************************/

//  VOID   _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
//  {
    .globl  _tx_thread_stack_build
    .type   _tx_thread_stack_build,@function
    .align  4
_tx_thread_stack_build:

    ENTRY0

    /* Get logical base of stack area (top). */
    l32i    a5, a2, tx_thread_stack_end /* get top-1 of stack area */
    addi    a5, a5, 1                   /* undo the -1 */
    srli    a5, a5, 4                   /* force 16-byte alignment */
    slli    a5, a5, 4                   /* a5 = post-dispatch SP (frame top) */

    /* Allocate space for the frame (frame size is already 16-byte aligned). */
    addi    a4, a5, -XT_STK_FRMSZ       /* a4 = pre-dispatch SP (frame base) */

    /* Set the thread's SP. */
    s32i    a4, a2, tx_thread_stack_ptr

#if !XCHAL_HAVE_XEA2
    addi    a4, a4, XT_STK_XTRA_SZ      /* a4 = base of exception frame */
#endif

    /* Clear the entire frame. (XEA3: only exception frame) */
    movi    a6, 0                       /* a6 = 0 */
    mov     a7, a4                      /* a7 = ptr to current word */
1:  s32i    a6, a7, 0                   /* clear current word */
    addi    a7, a7, 4                   /* point to next word */
    bltu    a7, a5, 1b                  /* repeat until frame top */

#if XCHAL_HAVE_XEA2
    s32i    a5, a4, XT_STK_A1           /* save post-dispatch SP in frame */
#endif

    /* Indicate a solicited or interrupted stack frame. */
#if XCHAL_HAVE_XEA2
    movi    a7, 0                       /* interrupted */
#else
    movi    a7, 0                       /* solicited */
#endif
    s32i    a7, a2, tx_thread_solicited

    /*
    Terminate GDB backtrace in this thread at the "return function" by ensuring
    it's A0 == 0. Since frame was cleared, don't need to do this explicitly.
    s32i    a6, a4, XT_STK_A0
    */

    /* Set the return address to the return function. */
    /* Start thread via user exception exit dispatcher (could use any). */
#if XCHAL_HAVE_XEA2
    movi    a5, _xt_user_exit
    s32i    a5, a4, XT_STK_EXIT
#else
    movi    a5, 0
    s32i    a5, a4, XT_STK_ATOMCTL
#endif

    s32i    a3, a4, XT_STK_PC

    /*
    Set thread's initial PS for C code, all int levels enabled.
    XEA2: Since we dispatch via level 1 (_xt_user_exit), must set PS.EXCM,
      which will be cleared by 'rfe' after the dispatcher, to prevent
      interrupts happening when PS is restored during the exit dispatcher.
    XEA3: nothing special, other than setting the thread stack type.
    */
#if XCHAL_HAVE_XEA2
    #ifdef __XTENSA_CALL0_ABI__
    movi    a6, PS_UM | PS_EXCM
    #else
    movi    a6, PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1)  /* pretend 'call4' */
    #endif
#else
    movi    a6, PS_STACK_FIRSTKER
#endif
    s32i    a6, a4, XT_STK_PS

#if XCHAL_HAVE_XEA2
    #ifdef XT_USE_SWPRI
    /* Set the initial virtual priority mask value to all 1's */
    movi    a3, -1
    s32i    a3, a4, XT_STK_VPRI
    #endif
#endif

    RET0

//  }