1/*
2 * Copyright 2014, General Dynamics C4 Systems
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include <config.h>
8#include <api/debug.h>
9#include <types.h>
10#include <plat/machine.h>
11#include <model/statedata.h>
12#include <model/smp.h>
13#include <object/structures.h>
14#include <object/tcb.h>
15#include <benchmark/benchmark_track.h>
16
17/* Collective cpu states, including both pre core architecture dependant and independent data */
18SMP_STATE_DEFINE(smpStatedata_t, ksSMP[CONFIG_MAX_NUM_NODES] ALIGN(L1_CACHE_LINE_SIZE));
19
20/* Global count of how many cpus there are */
21word_t ksNumCPUs;
22
23/* Pointer to the head of the scheduler queue for each priority */
24UP_STATE_DEFINE(tcb_queue_t, ksReadyQueues[NUM_READY_QUEUES]);
25UP_STATE_DEFINE(word_t, ksReadyQueuesL1Bitmap[CONFIG_NUM_DOMAINS]);
26UP_STATE_DEFINE(word_t, ksReadyQueuesL2Bitmap[CONFIG_NUM_DOMAINS][L2_BITMAP_SIZE]);
27compile_assert(ksReadyQueuesL1BitmapBigEnough, (L2_BITMAP_SIZE - 1) <= wordBits)
28#ifdef CONFIG_KERNEL_MCS
29/* Head of the queue of threads waiting for their budget to be replenished */
30UP_STATE_DEFINE(tcb_t *, ksReleaseHead);
31#endif
32
33/* Current thread TCB pointer */
34UP_STATE_DEFINE(tcb_t *, ksCurThread);
35
36/* Idle thread TCB pointer */
37UP_STATE_DEFINE(tcb_t *, ksIdleThread);
38
39/* Values of 0 and ~0 encode ResumeCurrentThread and ChooseNewThread
40 * respectively; other values encode SwitchToThread and must be valid
41 * tcb pointers */
42UP_STATE_DEFINE(tcb_t *, ksSchedulerAction);
43
44#ifdef CONFIG_HAVE_FPU
45/* Currently active FPU state, or NULL if there is no active FPU state */
46UP_STATE_DEFINE(user_fpu_state_t *, ksActiveFPUState);
47
48UP_STATE_DEFINE(word_t, ksFPURestoresSinceSwitch);
49#endif /* CONFIG_HAVE_FPU */
50#ifdef CONFIG_KERNEL_MCS
51/* the amount of time passed since the kernel time was last updated */
52UP_STATE_DEFINE(ticks_t, ksConsumed);
53/* whether we need to reprogram the timer before exiting the kernel */
54UP_STATE_DEFINE(bool_t, ksReprogram);
55/* the current kernel time (recorded on kernel entry) */
56UP_STATE_DEFINE(ticks_t, ksCurTime);
57/* current scheduling context pointer */
58UP_STATE_DEFINE(sched_context_t *, ksCurSC);
59#endif
60
61#ifdef CONFIG_DEBUG_BUILD
62UP_STATE_DEFINE(tcb_t *, ksDebugTCBs);
63#endif /* CONFIG_DEBUG_BUILD */
64#ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
65UP_STATE_DEFINE(bool_t, benchmark_log_utilisation_enabled);
66UP_STATE_DEFINE(timestamp_t, benchmark_start_time);
67UP_STATE_DEFINE(timestamp_t, benchmark_end_time);
68UP_STATE_DEFINE(timestamp_t, benchmark_kernel_time);
69UP_STATE_DEFINE(timestamp_t, benchmark_kernel_number_entries);
70UP_STATE_DEFINE(timestamp_t, benchmark_kernel_number_schedules);
71#endif /* CONFIG_BENCHMARK_TRACK_UTILISATION */
72
73/* Units of work we have completed since the last time we checked for
74 * pending interrupts */
75word_t ksWorkUnitsCompleted;
76
77irq_state_t intStateIRQTable[INT_STATE_ARRAY_SIZE];
78/* CNode containing interrupt handler endpoints - like all seL4 objects, this CNode needs to be
79 * of a size that is a power of 2 and aligned to its size. */
80cte_t intStateIRQNode[BIT(IRQ_CNODE_SLOT_BITS)] ALIGN(BIT(IRQ_CNODE_SLOT_BITS + seL4_SlotBits));
81compile_assert(irqCNodeSize, sizeof(intStateIRQNode) >= ((INT_STATE_ARRAY_SIZE) *sizeof(cte_t)));
82
83/* Currently active domain */
84dom_t ksCurDomain;
85
86/* Domain timeslice remaining */
87#ifdef CONFIG_KERNEL_MCS
88ticks_t ksDomainTime;
89#else
90word_t ksDomainTime;
91#endif
92
93/* An index into ksDomSchedule for active domain and length. */
94word_t ksDomScheduleIdx;
95
96/* Only used by lockTLBEntry */
97word_t tlbLockCount = 0;
98
99/* Idle thread. */
100SECTION("._idle_thread") char ksIdleThreadTCB[CONFIG_MAX_NUM_NODES][BIT(seL4_TCBBits)] ALIGN(BIT(TCB_SIZE_BITS));
101
102#ifdef CONFIG_KERNEL_MCS
103/* Idle thread Schedcontexts */
104char ksIdleThreadSC[CONFIG_MAX_NUM_NODES][BIT(seL4_MinSchedContextBits)] ALIGN(BIT(seL4_MinSchedContextBits));
105#endif
106
107#if (defined CONFIG_DEBUG_BUILD || defined CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES)
108kernel_entry_t ksKernelEntry;
109#endif /* DEBUG */
110
111#ifdef CONFIG_KERNEL_LOG_BUFFER
112paddr_t ksUserLogBuffer;
113#endif /* CONFIG_KERNEL_LOG_BUFFER */
114