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
16extern char kernel_stack_alloc[CONFIG_MAX_NUM_NODES][BIT(CONFIG_KERNEL_STACK_BITS)];
17
18void Arch_switchToThread(tcb_t *tcb)
19{
20    setVMRoot(tcb);
21}
22
23BOOT_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
41void 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
49void Arch_activateIdleThread(tcb_t *tcb)
50{
51    /* Don't need to do anything */
52}
53
54void Arch_postModifyRegisters(tcb_t *tptr)
55{
56    /* Nothing to do */
57}
58