summaryrefslogtreecommitdiff
path: root/common_smp/src/tx_initialize_kernel_enter.c
blob: 89c94dba24f76879edb272902fed225624c40c67 (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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/***************************************************************************
 * Copyright (c) 2024 Microsoft Corporation 
 * 
 * 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
 **************************************************************************/


/**************************************************************************/
/**************************************************************************/
/**                                                                       */
/** ThreadX Component                                                     */
/**                                                                       */
/**   Initialize                                                          */
/**                                                                       */
/**************************************************************************/
/**************************************************************************/

#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE


/* Include necessary system files.  */

#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_timer.h"


/* Define any port-specific scheduling data structures.  */

TX_PORT_SPECIFIC_DATA


#ifdef TX_SAFETY_CRITICAL
TX_SAFETY_CRITICAL_EXCEPTION_HANDLER
#endif


/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _tx_initialize_kernel_enter                        PORTABLE SMP     */
/*                                                           6.3.0        */
/*  AUTHOR                                                                */
/*                                                                        */
/*    William E. Lamie, Microsoft Corporation                             */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function is the first ThreadX function called during           */
/*    initialization.  It is called from the application's "main()"       */
/*    function.  It is important to note that this routine never          */
/*    returns.  The processing of this function is relatively simple:     */
/*    it calls several ThreadX initialization functions (if needed),      */
/*    calls the application define function, and then invokes the         */
/*    scheduler.                                                          */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    None                                                                */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*    _tx_thread_smp_high_level_initialize  SMP initialization            */
/*    _tx_thread_smp_current_state_set  Set system state for all cores    */
/*    _tx_initialize_low_level          Low-level initialization          */
/*    _tx_initialize_high_level         High-level initialization         */
/*    tx_application_define             Application define function       */
/*    _tx_thread_scheduler              ThreadX scheduling loop           */
/*                                                                        */
/*  CALLED BY                                                             */
/*                                                                        */
/*    main                              Application main program          */
/*                                                                        */
/*  RELEASE HISTORY                                                       */
/*                                                                        */
/*    DATE              NAME                      DESCRIPTION             */
/*                                                                        */
/*  09-30-2020      William E. Lamie        Initial Version 6.1           */
/*  10-31-2023      Xiuwen Cai              Modified comment(s),          */
/*                                            added random generator      */
/*                                            initialization,             */
/*                                            resulting in version 6.3.0  */
/*                                                                        */
/**************************************************************************/
VOID  _tx_initialize_kernel_enter(VOID)
{

ULONG   other_core_status, i;


    /* Determine if the compiler has pre-initialized ThreadX.  */
    if (_tx_thread_system_state[0] != TX_INITIALIZE_ALMOST_DONE)
    {

        /* No, the initialization still needs to take place.  */

        /* Ensure that the system state variable is set to indicate
           initialization is in progress.  Note that this variable is
           later used to represent interrupt nesting.  */
        _tx_thread_smp_current_state_set(TX_INITIALIZE_IN_PROGRESS);

        /* Call any port specific preprocessing.  */
        TX_PORT_SPECIFIC_PRE_INITIALIZATION

        /* Invoke the low-level initialization to handle all processor specific
           initialization issues.  */
        _tx_initialize_low_level();

        /* Call the high-level SMP  Initialization.  */
        _tx_thread_smp_high_level_initialize();

        /* Invoke the high-level initialization to exercise all of the
           ThreadX components and the application's initialization
           function.  */
        _tx_initialize_high_level();

        /* Call any port specific post-processing.  */
        TX_PORT_SPECIFIC_POST_INITIALIZATION
    }

    /* Optional processing extension.  */
    TX_INITIALIZE_KERNEL_ENTER_EXTENSION

    /* Ensure that the system state variable is set to indicate
       initialization is in progress.  Note that this variable is
       later used to represent interrupt nesting.  */
    _tx_thread_system_state[0] =  TX_INITIALIZE_IN_PROGRESS;

    /* Optional random number generator initialization.  */
    TX_INITIALIZE_RANDOM_GENERATOR_INITIALIZATION

    /* Call the application provided initialization function.  Pass the
       first available memory address to it.  */
    tx_application_define(_tx_initialize_unused_memory);

    /* Call any port specific pre-scheduler processing.  */
    TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION

    /* Now wait for all cores to become ready for scheduling.  */
    do
    {

        /* Release the other cores from initialization.  */
        _tx_thread_smp_release_cores_flag =  TX_TRUE;

        /* Add all the status together...  Other cores must clear their system
           state before they they are released.  */
        other_core_status =  ((ULONG) 0);

#ifndef TX_THREAD_SMP_DYNAMIC_CORE_MAX
        for (i = ((ULONG) 1); i < ((ULONG) TX_THREAD_SMP_MAX_CORES); i++)
#else
        for (i = ((ULONG) 1); i < _tx_thread_smp_max_cores; i++)
#endif
        {


            /* Call port-specific memory synchronization primitive.  */
            TX_PORT_SPECIFIC_MEMORY_SYNCHRONIZATION

            /* Add the states of each subsequent core.  */
            other_core_status =  other_core_status + _tx_thread_system_state[i];
        }

    } while (other_core_status != ((ULONG) 0));

    /* Set the system state in preparation for entering the thread
       scheduler.  */
    _tx_thread_system_state[0] =  TX_INITIALIZE_IS_FINISHED;

    /* Call port-specific memory synchronization primitive.  */
    TX_PORT_SPECIFIC_MEMORY_SYNCHRONIZATION

    /* Enter the scheduling loop to start executing threads!  */
    _tx_thread_schedule();

#ifdef TX_SAFETY_CRITICAL

    /* If we ever get here, raise safety critical exception.  */
    TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
#endif
}