1 /*
2  * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
3  * Copyright 2015, 2016 Hesham Almatary <heshamelmatary@gmail.com>
4  *
5  * SPDX-License-Identifier: GPL-2.0-only
6  */
7 
8 #include <config.h>
9 #include <object.h>
10 #include <machine.h>
11 #include <arch/model/statedata.h>
12 #include <arch/kernel/vspace.h>
13 #include <arch/kernel/thread.h>
14 #include <linker.h>
15 
16 extern char kernel_stack_alloc[CONFIG_MAX_NUM_NODES][BIT(CONFIG_KERNEL_STACK_BITS)];
17 
Arch_switchToThread(tcb_t * tcb)18 void Arch_switchToThread(tcb_t *tcb)
19 {
20     setVMRoot(tcb);
21 }
22 
Arch_configureIdleThread(tcb_t * tcb)23 BOOT_CODE void Arch_configureIdleThread(tcb_t *tcb)
24 {
25     setRegister(tcb, NextIP, (word_t)idleThreadStart);
26 
27     /* Enable interrupts and keep working in supervisor mode */
28     setRegister(tcb, SSTATUS, (word_t) SSTATUS_SPP | SSTATUS_SPIE);
29 #ifdef ENABLE_SMP_SUPPORT
30     for (int i = 0; i < CONFIG_MAX_NUM_NODES; i++) {
31         if (NODE_STATE_ON_CORE(ksIdleThread, i) == tcb) {
32             setRegister(tcb, SP, (word_t)kernel_stack_alloc + (i + 1) * BIT(CONFIG_KERNEL_STACK_BITS));
33             break;
34         }
35     }
36 #else
37     setRegister(tcb, SP, (word_t)kernel_stack_alloc + BIT(CONFIG_KERNEL_STACK_BITS));
38 #endif
39 }
40 
Arch_switchToIdleThread(void)41 void Arch_switchToIdleThread(void)
42 {
43     tcb_t *tcb = NODE_STATE(ksIdleThread);
44 
45     /* Force the idle thread to run on kernel page table */
46     setVMRoot(tcb);
47 }
48 
Arch_activateIdleThread(tcb_t * tcb)49 void Arch_activateIdleThread(tcb_t *tcb)
50 {
51     /* Don't need to do anything */
52 }
53 
Arch_postModifyRegisters(tcb_t * tptr)54 void Arch_postModifyRegisters(tcb_t *tptr)
55 {
56     /* Nothing to do */
57 }
58