summaryrefslogtreecommitdiffstats
path: root/import/chips/p9/procedures/ppe_closed/cme/p9_cme_main.c
blob: 723a740e3ade5b51a6c5a00799f08230dca1833c (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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: import/chips/p9/procedures/ppe_closed/cme/p9_cme_main.c $     */
/*                                                                        */
/* OpenPOWER HCODE Project                                                */
/*                                                                        */
/* COPYRIGHT 2015,2017                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

#include "pk.h"
#include "p9_cme_irq.h"
#include "p9_cme_flags.h"
#include "p9_hcode_image_defines.H"

// CME Pstate Header and Structure
#include "p9_cme_pstate.h"
CmePstateRecord G_cme_pstate_record;

// CME Stop Header and Structure
#include "p9_cme_stop.h"
CmeStopRecord G_cme_stop_record = {0};

#if TEST_ONLY_BCE_IRR
#include "p9_cme_copy_scan_ring.h"
BceIrritator G_bce_irr = {0};
#endif

// CME Interrupt Handler Table
EXTERNAL_IRQ_TABLE_START
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_DEBUGGER
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_DEBUG_TRIGGER
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_QUAD_CHECKSTOP
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_PVREF_FAIL
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_OCC_HEARTBEAT_LOST
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_CORE_CHECKSTOP
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_DROPOUT_FAIL
IRQ_HANDLER(p9_cme_pstate_intercme_in0_handler, (void*)NULL)
//CMEHW_IRQ_INTERCME_DIRECT_IN0
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_BCE_BUSY_HIGH
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_BCE_TIMEOUT
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_DOORBELL3_C0
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_DOORBELL3_C1
IRQ_HANDLER(p9_cme_stop_exit_handler, (void*) & (G_cme_stop_record.sem[1]))
//CMEHW_IRQ_PC_INTR_PENDING_C0
IRQ_HANDLER(p9_cme_stop_exit_handler, (void*) & (G_cme_stop_record.sem[1]))
//CMEHW_IRQ_PC_INTR_PENDING_C1
IRQ_HANDLER(p9_cme_stop_spwu_handler, (void*) & (G_cme_stop_record.sem[1]))
//CMEHW_IRQ_SPECIAL_WAKEUP_C0
IRQ_HANDLER(p9_cme_stop_spwu_handler, (void*) & (G_cme_stop_record.sem[1]))
//CMEHW_IRQ_SPECIAL_WAKEUP_C1
IRQ_HANDLER(p9_cme_stop_exit_handler, (void*) & (G_cme_stop_record.sem[1]))
//CMEHW_IRQ_REG_WAKEUP_C0
IRQ_HANDLER(p9_cme_stop_exit_handler, (void*) & (G_cme_stop_record.sem[1]))
//CMEHW_IRQ_REG_WAKEUP_C1
IRQ_HANDLER(p9_cme_stop_db2_handler, 0)     //CMEHW_IRQ_DOORBELL2_C0
IRQ_HANDLER(p9_cme_stop_db2_handler, 0)     //CMEHW_IRQ_DOORBELL2_C1
IRQ_HANDLER(p9_cme_stop_enter_handler, (void*) & (G_cme_stop_record.sem[0]))
//CMEHW_IRQ_PC_PM_STATE_ACTIVE_C0
IRQ_HANDLER(p9_cme_stop_enter_handler, (void*) & (G_cme_stop_record.sem[0]))
//CMEHW_IRQ_PC_PM_STATE_ACTIVE_C1
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_L2_PURGE_DONE
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_NCU_PURGE_DONE
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_CHTM_PURGE_DONE_C0
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_CHTM_PURGE_DONE_C1
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_BCE_BUSY_LOW
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_FINAL_VDM_DATA0
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_FINAL_VDM_DATA1
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_COMM_RECVD
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_COMM_SEND_ACK
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_COMM_SEND_NACK
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_SPARE_32
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_SPARE_33
IRQ_HANDLER(p9_cme_pstate_pmcr_handler, (void*) & (G_cme_pstate_record.sem[0]))
//CMEHW_IRQ_PMCR_UPDATE_C0
IRQ_HANDLER(p9_cme_pstate_pmcr_handler, (void*) & (G_cme_pstate_record.sem[0]))
//CMEHW_IRQ_PMCR_UPDATE_C1
IRQ_HANDLER(p9_cme_pstate_db_handler, (void*) & (G_cme_pstate_record.sem[1]))
//CMEHW_IRQ_DOORBELL0_C0
IRQ_HANDLER(p9_cme_pstate_db_handler, (void*) & (G_cme_pstate_record.sem[1]))
//CMEHW_IRQ_DOORBELL0_C1
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_INTERCME_IN1
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_INTERCME_IN2
IRQ_HANDLER(p9_cme_stop_db1_handler, 0)     //CMEHW_IRQ_DOORBELL1_C0
IRQ_HANDLER(p9_cme_stop_db1_handler, 0)     //CMEHW_IRQ_DOORBELL1_C1
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_PECE_INTR_DISABLED_C0
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_PECE_INTR_DISABLED_C1
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_44
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_45
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_46
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_47
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_48
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_49
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_50
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_51
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_52
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_53
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_54
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_55
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_56
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_57
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_58
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_59
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_60
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_61
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_62
IRQ_HANDLER_DEFAULT                         //CMEHW_IRQ_RESERVED_63
EXTERNAL_IRQ_TABLE_END

#define  KERNEL_STACK_SIZE                 256

#define  CME_THREAD_STACK_SIZE_STOP_EXIT   512
#define  CME_THREAD_STACK_SIZE_STOP_ENTRY  256
#define  CME_THREAD_STACK_SIZE_PSTATE_DB   256
#define  CME_THREAD_STACK_SIZE_PSTATE_PMCR 256
#if TEST_ONLY_BCE_IRR
    #define  CME_THREAD_STACK_SIZE_BCE_IRR     256
#endif

#define  CME_THREAD_PRIORITY_STOP_EXIT     1
#define  CME_THREAD_PRIORITY_STOP_ENTRY    2
#define  CME_THREAD_PRIORITY_PSTATE_DB     3
#define  CME_THREAD_PRIORITY_PSTATE_PMCR   4
#if TEST_ONLY_BCE_IRR
    #define  CME_THREAD_PRIORITY_BCE_IRR       30
#endif

uint8_t  G_kernel_stack[KERNEL_STACK_SIZE];

uint8_t  G_p9_cme_stop_exit_thread_stack[CME_THREAD_STACK_SIZE_STOP_EXIT];
uint8_t  G_p9_cme_stop_enter_thread_stack[CME_THREAD_STACK_SIZE_STOP_ENTRY];
uint8_t  G_p9_cme_db_thread_stack[CME_THREAD_STACK_SIZE_PSTATE_DB];
uint8_t  G_p9_cme_pmcr_thread_stack[CME_THREAD_STACK_SIZE_PSTATE_PMCR];
#if TEST_ONLY_BCE_IRR
    uint8_t  G_p9_cme_bce_irr_thread_stack[CME_THREAD_STACK_SIZE_BCE_IRR];
#endif

PkThread G_p9_cme_stop_exit_thread;
PkThread G_p9_cme_stop_enter_thread;
PkThread G_p9_cme_db_thread;
PkThread G_p9_cme_pmcr_thread;
#if TEST_ONLY_BCE_IRR
    PkThread G_p9_cme_bce_irr_thread;
#endif

int
main(int argc, char** argv)
{
    // Initializes kernel data (stack, threads, timebase, timers, etc.)
    pk_initialize((PkAddress)G_kernel_stack,
                  KERNEL_STACK_SIZE,
                  0,
                  PPE_TIMEBASE_HZ);

    PK_TRACE("Kernel init completed");

    // reading header attributes and initialize the queued scom mode
    cmeHeader_t* pCmeImgHdr = (cmeHeader_t*)(CME_SRAM_BASE + CME_HEADER_IMAGE_OFFSET);
    G_cme_stop_record.header_flags = pCmeImgHdr->g_cme_mode_flags;

    if (G_cme_stop_record.header_flags & QUEUED_SCAN_DISABLE)
    {
        out32(CME_LCL_LMCR_CLR, BITS32(8, 2));
    }
    else
    {
        out32(CME_LCL_LMCR_OR, BITS32(8, 2));
    }

    // Unified interrupt handler checks
    if (IDX_PRTY_LVL_DISABLED != (NUM_EXT_IRQ_PRTY_LEVELS - 1))
    {
        MY_TRACE_ERR("Code bug: IDX_PRTY_LVL_DISABLED(=%d)!=NUM_EXT_IRQ_PRTY_LEVELS(=%d)-1",
                     IDX_PRTY_LVL_DISABLED, NUM_EXT_IRQ_PRTY_LEVELS);
        pk_halt();
    }

    if (IRQ_VEC_PRTY_CHECK != 0xFFFFFFFFFFFFFFFF)
    {
        MY_TRACE_ERR("Code bug: IRQ_VEC_PRTY_CHECK=0x%08x%08x should be all ones",
                     IRQ_VEC_PRTY_CHECK);
        pk_halt();
    }


    //Currently, commenting this.
    //This shouldn't really be here at all as SGPE will write this register.
    //For verification in SIMICS, SOA, EPM currently just write the CME_LCL_FLAGS manually
    //
    //
    //
    /*   //CMO-Temporary setting
    // Setup up CME_LCL_FLAGS to indicate whether
    // this CME is QMGR master or slave.
    // Rules:
    // - If even CME then set FLAGS(3)=1. Otherwise =0.
    // - Whether in CME or Simics or HW,
    //   the assumption here is that the even CME in
    //   a configured Quad is always configured.
    uint32_t l_pir;
    asm volatile ("mfpir %[data] \n" : [data]"=r"(l_pir) );

    #ifndef _SOA_SC_ENVIRONMENT_
    if ( l_pir & PIR_INSTANCE_EVEN_ODD_MASK )
    {
        // Odd: Set slave status
        out32(CME_LCL_FLAGS_CLR, CME_FLAGS_QMGR_MASTER);
    }
    else
    {
        // Even: Set master status
        out32(CME_LCL_FLAGS_OR, CME_FLAGS_QMGR_MASTER);
    }

    #else

    if ( l_pir & PIR_INSTANCE_EVEN_ODD_MASK )
    {
        // Odd: Set slave status
        out32(CME_LCL_FLAGS_OR, CME_FLAGS_QMGR_MASTER);
    }
    else
    {
        // Even: Set master status
        out32(CME_LCL_FLAGS_CLR, CME_FLAGS_QMGR_MASTER);
    }

    #endif

    //\todo Fix  this
    #ifndef _SOA_SC_ENVIRONMENT_
    out32(CME_LCL_FLAGS_OR, CME_FLAGS_CORE0_GOOD | CME_FLAGS_CORE1_GOOD | CME_FLAGS_SIBLING_FUNCTIONAL);
    #else
    out32(CME_LCL_FLAGS_OR, CME_FLAGS_CORE0_GOOD | CME_FLAGS_CORE1_GOOD);
    #endif
    */
    // Initialize the thread control block for G_p9_cme_stop_exit_thread
    pk_thread_create(&G_p9_cme_stop_exit_thread,
                     (PkThreadRoutine)p9_cme_stop_exit_thread,
                     (void*)NULL,
                     (PkAddress)G_p9_cme_stop_exit_thread_stack,
                     (size_t)CME_THREAD_STACK_SIZE_STOP_EXIT,
                     (PkThreadPriority)CME_THREAD_PRIORITY_STOP_EXIT);

    PK_TRACE_BIN("G_p9_cme_stop_exit_thread",
                 &G_p9_cme_stop_exit_thread,
                 sizeof(G_p9_cme_stop_exit_thread));

    // Initialize the thread control block for G_p9_cme_stop_enter_thread
    pk_thread_create(&G_p9_cme_stop_enter_thread,
                     (PkThreadRoutine)p9_cme_stop_enter_thread,
                     (void*)NULL,
                     (PkAddress)G_p9_cme_stop_enter_thread_stack,
                     (size_t)CME_THREAD_STACK_SIZE_STOP_ENTRY,
                     (PkThreadPriority)CME_THREAD_PRIORITY_STOP_ENTRY);

    PK_TRACE_BIN("G_p9_cme_stop_enter_thread",
                 &G_p9_cme_stop_enter_thread,
                 sizeof(G_p9_cme_stop_enter_thread));

    // Initialize thread control blocks for the threads
    pk_thread_create( &G_p9_cme_db_thread,
                      (PkThreadRoutine)p9_cme_pstate_db_thread,
                      (void*)NULL,
                      (PkAddress)G_p9_cme_db_thread_stack,
                      (size_t)CME_THREAD_STACK_SIZE_PSTATE_DB,
                      (PkThreadPriority)CME_THREAD_PRIORITY_PSTATE_DB);

    PK_TRACE_BIN("G_p9_cme_db_thread",
                 &G_p9_cme_db_thread,
                 sizeof(G_p9_cme_db_thread));

    // Initialize thread control blocks for the threads
    pk_thread_create( &G_p9_cme_pmcr_thread,
                      (PkThreadRoutine)p9_cme_pstate_pmcr_thread,
                      (void*)NULL,
                      (PkAddress)G_p9_cme_pmcr_thread_stack,
                      (size_t)CME_THREAD_STACK_SIZE_PSTATE_PMCR,
                      (PkThreadPriority)CME_THREAD_PRIORITY_PSTATE_PMCR);

    PK_TRACE_BIN("G_p9_cme_pmcr_thread",
                 &G_p9_cme_pmcr_thread,
                 sizeof(G_p9_cme_pmcr_thread));

#if TEST_ONLY_BCE_IRR

    if ((G_bce_irr.enable = in32(CME_LCL_FLAGS) & FLAG_BCE_IRR_ENABLE))
    {
        // Initialize thread control blocks for the threads
        pk_thread_create( &G_p9_cme_bce_irr_thread,
                          (PkThreadRoutine)bce_irr_run,
                          (void*)NULL,
                          (PkAddress)G_p9_cme_bce_irr_thread_stack,
                          (size_t)CME_THREAD_STACK_SIZE_BCE_IRR,
                          (PkThreadPriority)CME_THREAD_PRIORITY_BCE_IRR);

        PK_TRACE_BIN("G_p9_cme_bce_irr_thread",
                     &G_p9_cme_bce_irr_thread,
                     sizeof(G_p9_cme_bce_irr_thread));
    }

#endif

    // Make G_p9_cme_stop_exit_thread runnable
    pk_thread_resume(&G_p9_cme_stop_exit_thread);

    // Make G_p9_cme_stop_enter_thread runnable
    pk_thread_resume(&G_p9_cme_stop_enter_thread);

    // Make G_p9_cme_pstate_thread runnable
    pk_thread_resume(&G_p9_cme_db_thread);

    // Make G_p9_cme_pstate_thread runnable
    pk_thread_resume(&G_p9_cme_pmcr_thread);

#if TEST_ONLY_BCE_IRR

    if (G_bce_irr.enable)
    {
        // Make G_p9_cme_bce_irr_thread runnable
        pk_thread_resume(&G_p9_cme_bce_irr_thread);
    }

#endif

    PK_TRACE("Launching threads");

    ppe42_app_ctx_set(0);

    // Start running the highest priority thread.
    // This function never returns
    pk_start_threads();

    return 0;
}
OpenPOWER on IntegriCloud