[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);
+	}
+
+
+}
+