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() 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
58NODE_STATE_BEGIN(nodeState)
59NODE_STATE_DECLARE(tcb_queue_t, ksReadyQueues[NUM_READY_QUEUES]);
60NODE_STATE_DECLARE(word_t, ksReadyQueuesL1Bitmap[CONFIG_NUM_DOMAINS]);
61NODE_STATE_DECLARE(word_t, ksReadyQueuesL2Bitmap[CONFIG_NUM_DOMAINS][L2_BITMAP_SIZE]);
62NODE_STATE_DECLARE(tcb_t, *ksCurThread);
63NODE_STATE_DECLARE(tcb_t, *ksIdleThread);
64NODE_STATE_DECLARE(tcb_t, *ksSchedulerAction);
65
66#ifdef CONFIG_KERNEL_MCS
67NODE_STATE_DECLARE(tcb_t, *ksReleaseHead);
68NODE_STATE_DECLARE(time_t, ksConsumed);
69NODE_STATE_DECLARE(time_t, ksCurTime);
70NODE_STATE_DECLARE(bool_t, ksReprogram);
71NODE_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 */
76NODE_STATE_DECLARE(user_fpu_state_t *, ksActiveFPUState);
77/* Number of times we have restored a user context with an active FPU without switching it */
78NODE_STATE_DECLARE(word_t, ksFPURestoresSinceSwitch);
79#endif /* CONFIG_HAVE_FPU */
80#ifdef CONFIG_DEBUG_BUILD
81NODE_STATE_DECLARE(tcb_t *, ksDebugTCBs);
82#endif /* CONFIG_DEBUG_BUILD */
83#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
84NODE_STATE_DECLARE(bool_t, benchmark_log_utilisation_enabled);
85NODE_STATE_DECLARE(timestamp_t, benchmark_start_time);
86NODE_STATE_DECLARE(timestamp_t, benchmark_end_time);
87NODE_STATE_DECLARE(timestamp_t, benchmark_kernel_time);
88NODE_STATE_DECLARE(timestamp_t, benchmark_kernel_number_entries);
89NODE_STATE_DECLARE(timestamp_t, benchmark_kernel_number_schedules);
90#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
91
92NODE_STATE_END(nodeState);
93
94extern 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
101extern word_t ksWorkUnitsCompleted;
102extern irq_state_t intStateIRQTable[];
103extern cte_t intStateIRQNode[];
104
105extern const dschedule_t ksDomSchedule[];
106extern const word_t ksDomScheduleLength;
107extern word_t ksDomScheduleIdx;
108extern dom_t ksCurDomain;
109#ifdef CONFIG_KERNEL_MCS
110extern ticks_t ksDomainTime;
111#else
112extern word_t ksDomainTime;
113#endif
114extern word_t tlbLockCount VISIBLE;
115
116extern char ksIdleThreadTCB[CONFIG_MAX_NUM_NODES][BIT(seL4_TCBBits)];
117
118#ifdef CONFIG_KERNEL_MCS
119extern char ksIdleThreadSC[CONFIG_MAX_NUM_NODES][BIT(seL4_MinSchedContextBits)];
120#endif
121
122#ifdef CONFIG_KERNEL_LOG_BUFFER
123extern 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