[Feature] add GA346 baseline version
Change-Id: Ic62933698569507dcf98240cdf5d9931ae34348f
diff --git a/src/tinysys/medmcu/drivers/common/scpctl/scp_scpctl.c b/src/tinysys/medmcu/drivers/common/scpctl/scp_scpctl.c
new file mode 100644
index 0000000..994d583
--- /dev/null
+++ b/src/tinysys/medmcu/drivers/common/scpctl/scp_scpctl.c
@@ -0,0 +1,215 @@
+/* Copyright Statement:
+ *
+ * This software/firmware and related documentation ("MediaTek Software") are
+ * protected under relevant copyright laws. The information contained herein
+ * is confidential and proprietary to MediaTek Inc. and/or its licensors.
+ * Without the prior written permission of MediaTek inc. and/or its licensors,
+ * any reproduction, modification, use or disclosure of MediaTek Software,
+ * and information contained herein, in whole or in part, shall be strictly prohibited.
+ */
+/* MediaTek Inc. (C) 2015. All rights reserved.
+ *
+ * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+ * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+ * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
+ * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+ * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+ * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+ * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
+ * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
+ * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
+ * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
+ * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
+ * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
+ * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+ * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+ * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
+ * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
+ */
+
+#include <FreeRTOS.h>
+#include <task.h>
+#ifdef CFG_LEGACY_IPI_SUPPORT
+#include <scp_ipi.h>
+#else
+#include <ipi.h>
+#include <ipi_id.h>
+#endif
+
+#include <scp_scpctl.h>
+#include <main.h>
+#include "encoding.h"
+#include "irq.h"
+#ifdef CFG_XGPT_SUPPORT
+#include <mt_gpt.h>
+#endif
+
+enum SCPCTL_STAT_E {
+ SCPCTL_STAT_INACTIVE = 0,
+ SCPCTL_STAT_ACTIVE,
+};
+
+struct scpctl_ctl_s {
+ enum SCPCTL_OP_E op;
+ enum SCPCTL_STAT_E stat;
+};
+
+#define mainCHECK_DELAY ((portTickType) 10000 / portTICK_RATE_MS)
+
+static struct scpctl_ctl_s scpctl __attribute__ ((section(".sync")));
+static char *prompt = "[SCPCTL]";
+static TaskHandle_t xMonitorTask = NULL;
+struct scpctl_cmd_s scpctl_cmd_s_buf __attribute__ ((section(".sync")));
+
+#ifdef CFG_SCP_STRESS_SUPPORT
+unsigned int task_stress_flag __attribute__((section(".sync"))) = 0;
+#endif
+
+#ifdef CFG_SCPCTL_TASK_STATUS
+static char list_buffer[512];
+
+static void __task_status(void)
+{
+ vTaskList(list_buffer);
+ PRINTF_E("Heap:free/total:%lu/%u\n", xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE);
+ PRINTF_E("Task Status:\n\r%s", list_buffer);
+// PRINTF_E("max dur.:%llu,limit:%llu\n", get_max_cs_duration_time(), get_max_cs_limit());
+}
+#endif
+
+void vTaskMonitor(void *pvParameters)
+{
+ portTickType xLastExecutionTime, xDelayTime;
+ xDelayTime = mainCHECK_DELAY;
+
+ do {
+ xLastExecutionTime = xTaskGetTickCount();
+
+#ifdef CFG_SCPCTL_TASK_STATUS
+ __task_status();
+#endif
+#ifdef CFG_MRV_UNALIGN_SUPPORT
+ PRINTF_E("unaligned Load/Store times (%u/%u)\n", misalignedLoad, misalignedStore);
+#endif
+ vTaskDelayUntil(&xLastExecutionTime, xDelayTime);
+ } while (1);
+}
+
+
+/****************************************************************************
+ * The ISR is to receive the IPI commands sent by ADB and then modify
+ * the operation, op, of the control state.
+ ****************************************************************************/
+static void scpctl_handler(unsigned int id, void *prdata, void *data, unsigned int len)
+{
+ struct scpctl_cmd_s *cmd = (struct scpctl_cmd_s *)data;
+ enum SCPCTL_TYPE_E type = cmd->type;
+ enum SCPCTL_OP_E op = cmd->op;
+
+ switch (type) {
+ case SCPCTL_TYPE_TMON:
+ scpctl.op = (op == SCPCTL_OP_ACTIVE)
+ ? SCPCTL_OP_ACTIVE
+ : SCPCTL_OP_INACTIVE;
+
+ PRINTF_E("%s: type/op=%d/%d,stat=%d\n", prompt, type, op, scpctl.stat);
+ break;
+#ifdef CFG_SCP_STRESS_SUPPORT
+ case SCPCTL_STRESS_TEST:
+ task_stress_flag = 1;
+ PRINTF_E("Stress enabled\n");
+ break;
+#endif
+ default:
+ PRINTF_E("%s: unknown cmd, %d, %d\n", prompt, type, op);
+ break;
+ }
+}
+
+/****************************************************************************
+ * The function is called by in vApplicationIdleHook and determine whether
+ * to resume or to suspend monitor task depending on the command and the
+ * current status.
+ *
+ * op = active, state = inactive --> resume monitor task.
+ * op = inactive, state = active --> suspend monitor task.
+ * others, keep the same status.
+ ****************************************************************************/
+void scpctl_idlehook(void)
+{
+ int op = scpctl.op;
+
+ if (op == SCPCTL_OP_ACTIVE && scpctl.stat == SCPCTL_STAT_INACTIVE) {
+ vTaskResume(xMonitorTask);
+ scpctl.stat = SCPCTL_STAT_ACTIVE;
+ }
+ else if (op == SCPCTL_OP_INACTIVE && scpctl.stat == SCPCTL_STAT_ACTIVE) {
+ vTaskSuspend(xMonitorTask);
+ scpctl.stat = SCPCTL_STAT_INACTIVE;
+ }
+}
+
+
+#ifdef CFG_SCP_STRESS_SUPPORT
+
+/* run on both core */
+static void vTaskSCPStress(void *pvParameters)
+{
+ portTickType xLastExecutionTime, xDelayTime;
+ xLastExecutionTime = xTaskGetTickCount();
+ unsigned int get_random_time;
+ xDelayTime = (portTickType) 60000 / portTICK_RATE_MS ;
+ do {
+ PRINTF_E("Task Stress ");
+ if (task_stress_flag == 0) {
+ PRINTF_E("status=%u\n", task_stress_flag);
+ } else {
+ /* stress flag is enable*/
+ PRINTF_E("status=%u, stress enable!\n", task_stress_flag);
+ /* get 60 ~120 sec delay*/
+#ifdef CFG_XGPT_SUPPORT
+ get_random_time = (unsigned int)(get_boot_time_ns() % 60);
+ get_random_time = (30 + get_random_time) * 1000;
+ xDelayTime = (portTickType) get_random_time / portTICK_RATE_MS ;
+#endif
+ PRINTF_E("after:%ums, will abort...\n", xDelayTime);
+ vTaskDelayUntil(&xLastExecutionTime, xDelayTime);
+ configASSERT(0);
+ }
+ xDelayTime = (portTickType) 60000 / portTICK_RATE_MS ;
+ vTaskDelayUntil(&xLastExecutionTime, xDelayTime);
+ } while (1);
+}
+#endif
+
+void scpctl_init(void)
+{
+ int ret = 0;
+
+ xTaskCreate(vTaskMonitor, "TMon", 384, (void*)4, PRI_MONITOR, &xMonitorTask);
+ configASSERT(xMonitorTask != NULL);
+#ifdef CFG_SCP_STRESS_SUPPORT
+ xTaskCreate(vTaskSCPStress, "Stres", 384, (void*)4, PRI_STRESS, NULL);
+#endif /* CFG_SCP_STRESS_SUPPORT */
+
+ if (scp_region_info.scpctl & (1 << SCPCTL_TYPE_TMON)) {
+ scpctl.stat = SCPCTL_STAT_ACTIVE;
+ scpctl.op = SCPCTL_OP_ACTIVE;
+ }
+ else { /* monitor task is in suspened state */
+ scpctl.stat = SCPCTL_STAT_INACTIVE;
+ scpctl.op = SCPCTL_OP_INACTIVE;
+ vTaskSuspend(xMonitorTask);
+ }
+ /* uni-control, do it only ine one core */
+ if (mrv_read_csr(CSR_MHARTID) == 1) {
+ ret = ipi_register(IPI_IN_SCPCTL_1, scpctl_handler, 0, &scpctl_cmd_s_buf);
+ if (ret)
+ PRINTF_E("IPI_IN_SCPCTL_1 %d\n", ret);
+ }
+
+
+}
+