1 /*
2 * Copyright (c) 2015 Travis Geiselbrecht
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <assert.h>
9 #include <lk/debug.h>
10 #include <lk/trace.h>
11 #include <sys/types.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <kernel/thread.h>
15 #include <arch/riscv.h>
16
17 #define LOCAL_TRACE 0
18
19 struct thread *_current_thread;
20
21 static void initial_thread_func(void) __NO_RETURN;
initial_thread_func(void)22 static void initial_thread_func(void) {
23 DEBUG_ASSERT(arch_ints_disabled());
24
25 thread_t *ct = get_current_thread();
26
27 #if LOCAL_TRACE
28 LTRACEF("thread %p calling %p with arg %p\n", ct, ct->entry, ct->arg);
29 dump_thread(ct);
30 #endif
31
32 /* release the thread lock that was implicitly held across the reschedule */
33 spin_unlock(&thread_lock);
34 arch_enable_ints();
35
36 int ret = ct->entry(ct->arg);
37
38 LTRACEF("thread %p exiting with %d\n", ct, ret);
39
40 thread_exit(ret);
41 }
42
arch_thread_initialize(thread_t * t)43 void arch_thread_initialize(thread_t *t) {
44 /* zero out the thread context */
45 memset(&t->arch.cs_frame, 0, sizeof(t->arch.cs_frame));
46
47 /* make sure the top of the stack is 16 byte aligned */
48 vaddr_t stack_top = ROUNDDOWN((vaddr_t)t->stack + t->stack_size, 16);
49
50 t->arch.cs_frame.sp = stack_top;
51 t->arch.cs_frame.ra = (vaddr_t)&initial_thread_func;
52
53 LTRACEF("t %p (%s) stack top %#lx entry %p arg %p\n", t, t->name, stack_top, t->entry, t->arg);
54 }
55
arch_context_switch(thread_t * oldthread,thread_t * newthread)56 void arch_context_switch(thread_t *oldthread, thread_t *newthread) {
57 DEBUG_ASSERT(arch_ints_disabled());
58
59 LTRACEF("old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name);
60
61 riscv_context_switch(&oldthread->arch.cs_frame, &newthread->arch.cs_frame);
62 }
63
arch_dump_thread(thread_t * t)64 void arch_dump_thread(thread_t *t) {
65 if (t->state != THREAD_RUNNING) {
66 dprintf(INFO, "\tarch: ");
67 dprintf(INFO, "sp %#lx\n", t->arch.cs_frame.sp);
68 }
69 }
70
71