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 */
18 SMP_STATE_DEFINE(smpStatedata_t, ksSMP[CONFIG_MAX_NUM_NODES] ALIGN(L1_CACHE_LINE_SIZE));
19 
20 /* Global count of how many cpus there are */
21 word_t ksNumCPUs;
22 
23 /* Pointer to the head of the scheduler queue for each priority */
24 UP_STATE_DEFINE(tcb_queue_t, ksReadyQueues[NUM_READY_QUEUES]);
25 UP_STATE_DEFINE(word_t, ksReadyQueuesL1Bitmap[CONFIG_NUM_DOMAINS]);
26 UP_STATE_DEFINE(word_t, ksReadyQueuesL2Bitmap[CONFIG_NUM_DOMAINS][L2_BITMAP_SIZE]);
27 compile_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 */
30 UP_STATE_DEFINE(tcb_t *, ksReleaseHead);
31 #endif
32 
33 /* Current thread TCB pointer */
34 UP_STATE_DEFINE(tcb_t *, ksCurThread);
35 
36 /* Idle thread TCB pointer */
37 UP_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 */
42 UP_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 */
46 UP_STATE_DEFINE(user_fpu_state_t *, ksActiveFPUState);
47 
48 UP_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 */
52 UP_STATE_DEFINE(ticks_t, ksConsumed);
53 /* whether we need to reprogram the timer before exiting the kernel */
54 UP_STATE_DEFINE(bool_t, ksReprogram);
55 /* the current kernel time (recorded on kernel entry) */
56 UP_STATE_DEFINE(ticks_t, ksCurTime);
57 /* current scheduling context pointer */
58 UP_STATE_DEFINE(sched_context_t *, ksCurSC);
59 #endif
60 
61 #ifdef CONFIG_DEBUG_BUILD
62 UP_STATE_DEFINE(tcb_t *, ksDebugTCBs);
63 #endif /* CONFIG_DEBUG_BUILD */
64 #ifdef CONFIG_BENCHMARK_TRACK_UTILISATION
65 UP_STATE_DEFINE(bool_t, benchmark_log_utilisation_enabled);
66 UP_STATE_DEFINE(timestamp_t, benchmark_start_time);
67 UP_STATE_DEFINE(timestamp_t, benchmark_end_time);
68 UP_STATE_DEFINE(timestamp_t, benchmark_kernel_time);
69 UP_STATE_DEFINE(timestamp_t, benchmark_kernel_number_entries);
70 UP_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 */
75 word_t ksWorkUnitsCompleted;
76 
77 irq_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. */
80 cte_t intStateIRQNode[BIT(IRQ_CNODE_SLOT_BITS)] ALIGN(BIT(IRQ_CNODE_SLOT_BITS + seL4_SlotBits));
81 compile_assert(irqCNodeSize, sizeof(intStateIRQNode) >= ((INT_STATE_ARRAY_SIZE) *sizeof(cte_t)));
82 
83 /* Currently active domain */
84 dom_t ksCurDomain;
85 
86 /* Domain timeslice remaining */
87 #ifdef CONFIG_KERNEL_MCS
88 ticks_t ksDomainTime;
89 #else
90 word_t ksDomainTime;
91 #endif
92 
93 /* An index into ksDomSchedule for active domain and length. */
94 word_t ksDomScheduleIdx;
95 
96 /* Only used by lockTLBEntry */
97 word_t tlbLockCount = 0;
98 
99 /* Idle thread. */
100 SECTION("._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 */
104 char 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)
108 kernel_entry_t ksKernelEntry;
109 #endif /* DEBUG */
110 
111 #ifdef CONFIG_KERNEL_LOG_BUFFER
112 paddr_t ksUserLogBuffer;
113 #endif /* CONFIG_KERNEL_LOG_BUFFER */
114