blob: 994d583dd04b6124e8094393aaa8ba766e0adc8b [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001/* Copyright Statement:
2 *
3 * This software/firmware and related documentation ("MediaTek Software") are
4 * protected under relevant copyright laws. The information contained herein
5 * is confidential and proprietary to MediaTek Inc. and/or its licensors.
6 * Without the prior written permission of MediaTek inc. and/or its licensors,
7 * any reproduction, modification, use or disclosure of MediaTek Software,
8 * and information contained herein, in whole or in part, shall be strictly prohibited.
9 */
10/* MediaTek Inc. (C) 2015. All rights reserved.
11 *
12 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
13 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
14 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
15 * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
18 * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
19 * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
20 * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
21 * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
22 * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
23 * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
24 * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
25 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
26 * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
27 * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
28 * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
29 * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
30 */
31
32#include <FreeRTOS.h>
33#include <task.h>
34#ifdef CFG_LEGACY_IPI_SUPPORT
35#include <scp_ipi.h>
36#else
37#include <ipi.h>
38#include <ipi_id.h>
39#endif
40
41#include <scp_scpctl.h>
42#include <main.h>
43#include "encoding.h"
44#include "irq.h"
45#ifdef CFG_XGPT_SUPPORT
46#include <mt_gpt.h>
47#endif
48
49enum SCPCTL_STAT_E {
50 SCPCTL_STAT_INACTIVE = 0,
51 SCPCTL_STAT_ACTIVE,
52};
53
54struct scpctl_ctl_s {
55 enum SCPCTL_OP_E op;
56 enum SCPCTL_STAT_E stat;
57};
58
59#define mainCHECK_DELAY ((portTickType) 10000 / portTICK_RATE_MS)
60
61static struct scpctl_ctl_s scpctl __attribute__ ((section(".sync")));
62static char *prompt = "[SCPCTL]";
63static TaskHandle_t xMonitorTask = NULL;
64struct scpctl_cmd_s scpctl_cmd_s_buf __attribute__ ((section(".sync")));
65
66#ifdef CFG_SCP_STRESS_SUPPORT
67unsigned int task_stress_flag __attribute__((section(".sync"))) = 0;
68#endif
69
70#ifdef CFG_SCPCTL_TASK_STATUS
71static char list_buffer[512];
72
73static void __task_status(void)
74{
75 vTaskList(list_buffer);
76 PRINTF_E("Heap:free/total:%lu/%u\n", xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE);
77 PRINTF_E("Task Status:\n\r%s", list_buffer);
78// PRINTF_E("max dur.:%llu,limit:%llu\n", get_max_cs_duration_time(), get_max_cs_limit());
79}
80#endif
81
82void vTaskMonitor(void *pvParameters)
83{
84 portTickType xLastExecutionTime, xDelayTime;
85 xDelayTime = mainCHECK_DELAY;
86
87 do {
88 xLastExecutionTime = xTaskGetTickCount();
89
90#ifdef CFG_SCPCTL_TASK_STATUS
91 __task_status();
92#endif
93#ifdef CFG_MRV_UNALIGN_SUPPORT
94 PRINTF_E("unaligned Load/Store times (%u/%u)\n", misalignedLoad, misalignedStore);
95#endif
96 vTaskDelayUntil(&xLastExecutionTime, xDelayTime);
97 } while (1);
98}
99
100
101/****************************************************************************
102 * The ISR is to receive the IPI commands sent by ADB and then modify
103 * the operation, op, of the control state.
104 ****************************************************************************/
105static void scpctl_handler(unsigned int id, void *prdata, void *data, unsigned int len)
106{
107 struct scpctl_cmd_s *cmd = (struct scpctl_cmd_s *)data;
108 enum SCPCTL_TYPE_E type = cmd->type;
109 enum SCPCTL_OP_E op = cmd->op;
110
111 switch (type) {
112 case SCPCTL_TYPE_TMON:
113 scpctl.op = (op == SCPCTL_OP_ACTIVE)
114 ? SCPCTL_OP_ACTIVE
115 : SCPCTL_OP_INACTIVE;
116
117 PRINTF_E("%s: type/op=%d/%d,stat=%d\n", prompt, type, op, scpctl.stat);
118 break;
119#ifdef CFG_SCP_STRESS_SUPPORT
120 case SCPCTL_STRESS_TEST:
121 task_stress_flag = 1;
122 PRINTF_E("Stress enabled\n");
123 break;
124#endif
125 default:
126 PRINTF_E("%s: unknown cmd, %d, %d\n", prompt, type, op);
127 break;
128 }
129}
130
131/****************************************************************************
132 * The function is called by in vApplicationIdleHook and determine whether
133 * to resume or to suspend monitor task depending on the command and the
134 * current status.
135 *
136 * op = active, state = inactive --> resume monitor task.
137 * op = inactive, state = active --> suspend monitor task.
138 * others, keep the same status.
139 ****************************************************************************/
140void scpctl_idlehook(void)
141{
142 int op = scpctl.op;
143
144 if (op == SCPCTL_OP_ACTIVE && scpctl.stat == SCPCTL_STAT_INACTIVE) {
145 vTaskResume(xMonitorTask);
146 scpctl.stat = SCPCTL_STAT_ACTIVE;
147 }
148 else if (op == SCPCTL_OP_INACTIVE && scpctl.stat == SCPCTL_STAT_ACTIVE) {
149 vTaskSuspend(xMonitorTask);
150 scpctl.stat = SCPCTL_STAT_INACTIVE;
151 }
152}
153
154
155#ifdef CFG_SCP_STRESS_SUPPORT
156
157/* run on both core */
158static void vTaskSCPStress(void *pvParameters)
159{
160 portTickType xLastExecutionTime, xDelayTime;
161 xLastExecutionTime = xTaskGetTickCount();
162 unsigned int get_random_time;
163 xDelayTime = (portTickType) 60000 / portTICK_RATE_MS ;
164 do {
165 PRINTF_E("Task Stress ");
166 if (task_stress_flag == 0) {
167 PRINTF_E("status=%u\n", task_stress_flag);
168 } else {
169 /* stress flag is enable*/
170 PRINTF_E("status=%u, stress enable!\n", task_stress_flag);
171 /* get 60 ~120 sec delay*/
172#ifdef CFG_XGPT_SUPPORT
173 get_random_time = (unsigned int)(get_boot_time_ns() % 60);
174 get_random_time = (30 + get_random_time) * 1000;
175 xDelayTime = (portTickType) get_random_time / portTICK_RATE_MS ;
176#endif
177 PRINTF_E("after:%ums, will abort...\n", xDelayTime);
178 vTaskDelayUntil(&xLastExecutionTime, xDelayTime);
179 configASSERT(0);
180 }
181 xDelayTime = (portTickType) 60000 / portTICK_RATE_MS ;
182 vTaskDelayUntil(&xLastExecutionTime, xDelayTime);
183 } while (1);
184}
185#endif
186
187void scpctl_init(void)
188{
189 int ret = 0;
190
191 xTaskCreate(vTaskMonitor, "TMon", 384, (void*)4, PRI_MONITOR, &xMonitorTask);
192 configASSERT(xMonitorTask != NULL);
193#ifdef CFG_SCP_STRESS_SUPPORT
194 xTaskCreate(vTaskSCPStress, "Stres", 384, (void*)4, PRI_STRESS, NULL);
195#endif /* CFG_SCP_STRESS_SUPPORT */
196
197 if (scp_region_info.scpctl & (1 << SCPCTL_TYPE_TMON)) {
198 scpctl.stat = SCPCTL_STAT_ACTIVE;
199 scpctl.op = SCPCTL_OP_ACTIVE;
200 }
201 else { /* monitor task is in suspened state */
202 scpctl.stat = SCPCTL_STAT_INACTIVE;
203 scpctl.op = SCPCTL_OP_INACTIVE;
204 vTaskSuspend(xMonitorTask);
205 }
206 /* uni-control, do it only ine one core */
207 if (mrv_read_csr(CSR_MHARTID) == 1) {
208 ret = ipi_register(IPI_IN_SCPCTL_1, scpctl_handler, 0, &scpctl_cmd_s_buf);
209 if (ret)
210 PRINTF_E("IPI_IN_SCPCTL_1 %d\n", ret);
211 }
212
213
214}
215