1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2017 Intel Corporation. All rights reserved.
4 //
5 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6 // Tomasz Lauda <tomasz.lauda@linux.intel.com>
7
8 /**
9 * \file
10 * \brief Arch task implementation file
11 * \authors Liam Girdwood <liam.r.girdwood@linux.intel.com>
12 * Tomasz Lauda <tomasz.lauda@linux.intel.com>
13 */
14
15 #include <rtos/alloc.h>
16 #include <rtos/cache.h>
17 #include <sof/lib/cpu.h>
18 #include <sof/lib/memory.h>
19 #include <rtos/wait.h>
20 #include <sof/schedule/edf_schedule.h>
21 #include <sof/schedule/schedule.h>
22 #include <rtos/task.h>
23 #include <ipc/topology.h>
24
25 #include <xtensa/corebits.h>
26 #include <xtensa/xtruntime-frames.h>
27 #include <xtos-structs.h>
28 #include <errno.h>
29 #include <stddef.h>
30 #include <stdint.h>
31
task_main_secondary_core(void * data)32 enum task_state task_main_secondary_core(void *data)
33 {
34 #if CONFIG_MULTICORE
35 /* main audio processing loop */
36 while (1) {
37 /* sleep until next IDC or DMA */
38 wait_for_interrupt(0);
39 }
40 #endif
41
42 return SOF_TASK_STATE_COMPLETED;
43 }
44
task_main_get(void)45 struct task **task_main_get(void)
46 {
47 struct core_context *ctx = (struct core_context *)cpu_read_threadptr();
48
49 return &ctx->main_task;
50 }
51
task_context_get(void)52 volatile void *task_context_get(void)
53 {
54 struct core_context *ctx = (struct core_context *)cpu_read_threadptr();
55
56 return ctx->td.xtos_active_task;
57 }
58
task_context_set(void * task_ctx)59 void task_context_set(void *task_ctx)
60 {
61 struct core_context *ctx = (struct core_context *)cpu_read_threadptr();
62
63 ctx->td.xtos_active_task = task_ctx;
64 }
65
task_context_alloc(void ** task_ctx)66 int task_context_alloc(void **task_ctx)
67 {
68 *task_ctx = rzalloc(SOF_MEM_ZONE_SYS_RUNTIME, 0, SOF_MEM_CAPS_RAM,
69 sizeof(xtos_task_context));
70 if (!*task_ctx)
71 return -ENOMEM;
72 return 0;
73 }
74
task_context_init(void * task_ctx,void * entry,void * arg0,void * arg1,int task_core,void * stack,int stack_size)75 int task_context_init(void *task_ctx, void *entry, void *arg0, void *arg1,
76 int task_core, void *stack, int stack_size)
77 {
78 xtos_task_context *ctx = task_ctx;
79 UserFrame *sp;
80
81 /* allocate stack if not provided */
82 if (stack) {
83 ctx->stack_base = stack;
84 ctx->stack_size = stack_size;
85 } else {
86 ctx->stack_base = rballoc(0, SOF_MEM_CAPS_RAM,
87 PLATFORM_TASK_DEFAULT_STACK_SIZE);
88 if (!ctx->stack_base)
89 return -ENOMEM;
90 ctx->stack_size = PLATFORM_TASK_DEFAULT_STACK_SIZE;
91 ctx->flags |= XTOS_TASK_CONTEXT_OWN_STACK;
92 }
93 bzero(ctx->stack_base, ctx->stack_size);
94
95 /* set initial stack pointer */
96 sp = (UserFrame *)((char *)ctx->stack_base + ctx->stack_size -
97 sizeof(UserFrame));
98
99 /* entry point */
100 sp->pc = (uint32_t)entry;
101
102 /* a1 is pointer to stack */
103 sp->a1 = (uint32_t)sp;
104
105 /* PS_WOECALL4_ABI - window overflow and increment enable
106 * PS_UM - user vector mode enable
107 */
108 sp->ps = PS_WOECALL4_ABI | PS_UM;
109
110 /* a6 and a7 are the first parameters */
111 sp->a6 = (uint32_t)arg0;
112 sp->a7 = (uint32_t)arg1;
113
114 ctx->stack_pointer = sp;
115
116 return 0;
117 }
118
task_context_free(void * task_ctx)119 void task_context_free(void *task_ctx)
120 {
121 xtos_task_context *ctx = task_ctx;
122
123 if (ctx->flags & XTOS_TASK_CONTEXT_OWN_STACK)
124 rfree(ctx->stack_base);
125
126 ctx->stack_size = 0;
127 ctx->stack_pointer = NULL;
128
129 rfree(ctx);
130 }
131