1 /*
2  * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
7 #pragma once
8 
9 #include <config.h>
10 #include <types.h>
11 #include <object/structures.h>
12 #include <object/tcb.h>
13 #include <mode/types.h>
14 
15 #ifdef ENABLE_SMP_SUPPORT
16 #define NODE_STATE_BEGIN(_name)                 typedef struct _name {
17 #define NODE_STATE_END(_name)                   } _name ## _t
18 #define NODE_STATE_TYPE_DECLARE(_name, _state)  _name ## _t _state
19 #define NODE_STATE_DECLARE(_type, _state)       _type _state
20 
21 #define SMP_STATE_DEFINE(_type, _state)         _type _state
22 #define UP_STATE_DEFINE(_type, _state)
23 
24 #define SMP_COND_STATEMENT(_st)                 _st
25 #define SMP_TERNARY(_smp, _up)                  _smp
26 
27 #define MODE_NODE_STATE_ON_CORE(_state, _core)  ksSMP[(_core)].cpu.mode._state
28 #define ARCH_NODE_STATE_ON_CORE(_state, _core)  ksSMP[(_core)].cpu._state
29 #define NODE_STATE_ON_CORE(_state, _core)       ksSMP[(_core)].system._state
30 
31 #define CURRENT_CPU_INDEX() getCurrentCPUIndex()
32 
33 #else
34 
35 #define NODE_STATE_BEGIN(_name)
36 #define NODE_STATE_END(_name)
37 #define NODE_STATE_TYPE_DECLARE(_name, _state)
38 /* UP states are declared as VISIBLE so that they are accessible in assembly */
39 #define NODE_STATE_DECLARE(_type, _state)       extern _type _state VISIBLE
40 
41 #define SMP_STATE_DEFINE(_name, _state)
42 #define UP_STATE_DEFINE(_type, _state)          _type _state
43 
44 #define SMP_COND_STATEMENT(_st)
45 #define SMP_TERNARY(_smp, _up)                  _up
46 
47 #define MODE_NODE_STATE_ON_CORE(_state, _core) _state
48 #define ARCH_NODE_STATE_ON_CORE(_state, _core) _state
49 #define NODE_STATE_ON_CORE(_state, _core)      _state
50 
51 #define CURRENT_CPU_INDEX() SEL4_WORD_CONST(0)
52 
53 #endif /* ENABLE_SMP_SUPPORT */
54 
55 #define NUM_READY_QUEUES (CONFIG_NUM_DOMAINS * CONFIG_NUM_PRIORITIES)
56 #define L2_BITMAP_SIZE ((CONFIG_NUM_PRIORITIES + wordBits - 1) / wordBits)
57 
58 NODE_STATE_BEGIN(nodeState)
59 NODE_STATE_DECLARE(tcb_queue_t, ksReadyQueues[NUM_READY_QUEUES]);
60 NODE_STATE_DECLARE(word_t, ksReadyQueuesL1Bitmap[CONFIG_NUM_DOMAINS]);
61 NODE_STATE_DECLARE(word_t, ksReadyQueuesL2Bitmap[CONFIG_NUM_DOMAINS][L2_BITMAP_SIZE]);
62 NODE_STATE_DECLARE(tcb_t, *ksCurThread);
63 NODE_STATE_DECLARE(tcb_t, *ksIdleThread);
64 NODE_STATE_DECLARE(tcb_t, *ksSchedulerAction);
65 
66 #ifdef CONFIG_KERNEL_MCS
67 NODE_STATE_DECLARE(tcb_t, *ksReleaseHead);
68 NODE_STATE_DECLARE(time_t, ksConsumed);
69 NODE_STATE_DECLARE(time_t, ksCurTime);
70 NODE_STATE_DECLARE(bool_t, ksReprogram);
71 NODE_STATE_DECLARE(sched_context_t, *ksCurSC);
72 #endif
73 
74 #ifdef CONFIG_HAVE_FPU
75 /* Current state installed in the FPU, or NULL if the FPU is currently invalid */
76 NODE_STATE_DECLARE(user_fpu_state_t *, ksActiveFPUState);
77 /* Number of times we have restored a user context with an active FPU without switching it */
78 NODE_STATE_DECLARE(word_t, ksFPURestoresSinceSwitch);
79 #endif /* CONFIG_HAVE_FPU */
80 #ifdef CONFIG_DEBUG_BUILD
81 NODE_STATE_DECLARE(tcb_t *, ksDebugTCBs);
82 #endif /* CONFIG_DEBUG_BUILD */
83 #ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
84 NODE_STATE_DECLARE(bool_t, benchmark_log_utilisation_enabled);
85 NODE_STATE_DECLARE(timestamp_t, benchmark_start_time);
86 NODE_STATE_DECLARE(timestamp_t, benchmark_end_time);
87 NODE_STATE_DECLARE(timestamp_t, benchmark_kernel_time);
88 NODE_STATE_DECLARE(timestamp_t, benchmark_kernel_number_entries);
89 NODE_STATE_DECLARE(timestamp_t, benchmark_kernel_number_schedules);
90 #endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
91 
92 NODE_STATE_END(nodeState);
93 
94 extern word_t ksNumCPUs;
95 
96 #if defined ENABLE_SMP_SUPPORT && defined CONFIG_ARCH_ARM
97 #define INT_STATE_ARRAY_SIZE ((CONFIG_MAX_NUM_NODES - 1) * NUM_PPI + maxIRQ + 1)
98 #else
99 #define INT_STATE_ARRAY_SIZE (maxIRQ + 1)
100 #endif
101 extern word_t ksWorkUnitsCompleted;
102 extern irq_state_t intStateIRQTable[];
103 extern cte_t intStateIRQNode[];
104 
105 extern const dschedule_t ksDomSchedule[];
106 extern const word_t ksDomScheduleLength;
107 extern word_t ksDomScheduleIdx;
108 extern dom_t ksCurDomain;
109 #ifdef CONFIG_KERNEL_MCS
110 extern ticks_t ksDomainTime;
111 #else
112 extern word_t ksDomainTime;
113 #endif
114 extern word_t tlbLockCount VISIBLE;
115 
116 extern char ksIdleThreadTCB[CONFIG_MAX_NUM_NODES][BIT(seL4_TCBBits)];
117 
118 #ifdef CONFIG_KERNEL_MCS
119 extern char ksIdleThreadSC[CONFIG_MAX_NUM_NODES][BIT(seL4_MinSchedContextBits)];
120 #endif
121 
122 #ifdef CONFIG_KERNEL_LOG_BUFFER
123 extern paddr_t ksUserLogBuffer;
124 #endif /* CONFIG_KERNEL_LOG_BUFFER */
125 
126 #define SchedulerAction_ResumeCurrentThread ((tcb_t*)0)
127 #define SchedulerAction_ChooseNewThread ((tcb_t*) 1)
128 
129 #define MODE_NODE_STATE(_state)    MODE_NODE_STATE_ON_CORE(_state, getCurrentCPUIndex())
130 #define ARCH_NODE_STATE(_state)    ARCH_NODE_STATE_ON_CORE(_state, getCurrentCPUIndex())
131 #define NODE_STATE(_state)         NODE_STATE_ON_CORE(_state, getCurrentCPUIndex())
132 
133