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 <sof/lib/alloc.h>
16 #include <sof/lib/cache.h>
17 #include <sof/lib/cpu.h>
18 #include <sof/lib/memory.h>
19 #include <sof/lib/wait.h>
20 #include <sof/schedule/edf_schedule.h>
21 #include <sof/schedule/schedule.h>
22 #include <sof/schedule/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