aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Narkevitch <ainh@cypress.com>2020-01-15 13:58:47 -0800
committerDavid Hu <david.hu@arm.com>2020-01-23 01:47:17 +0000
commit995bb45fed30c65108e5189d0fd0cee78573fd18 (patch)
tree55414302d6ba35e3d736005e0b839cbc19ba38aa
parent1c7a69d06c63cc20fc4c30c6f657f121b3924dbb (diff)
downloadtrusted-firmware-m-995bb45fed30c65108e5189d0fd0cee78573fd18.tar.gz
Platform: Debug Access Port (DAP) driver (psoc64)
As specified by the default security policy, CM4 core debug port is disabled during the boot, but allowed to be enabled later after CM4 is up. Add an API to control DAP and enable CM4 debugging. Signed-off-by: Andrei Narkevitch <ainh@cypress.com> Change-Id: Ib9ee449bb21c8a26c75ac51c80be112608914ed8
-rw-r--r--platform/ext/psoc64.cmake1
-rw-r--r--platform/ext/target/cypress/psoc64/driver_dap.c80
-rw-r--r--platform/ext/target/cypress/psoc64/driver_dap.h36
-rw-r--r--platform/ext/target/cypress/psoc64/spm_hal.c9
4 files changed, 126 insertions, 0 deletions
diff --git a/platform/ext/psoc64.cmake b/platform/ext/psoc64.cmake
index baa1065e5..a98ea518e 100644
--- a/platform/ext/psoc64.cmake
+++ b/platform/ext/psoc64.cmake
@@ -215,6 +215,7 @@ if (NOT DEFINED BUILD_CMSIS_DRIVERS)
elseif(BUILD_CMSIS_DRIVERS)
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/cypress/psoc64/driver_smpu.c")
list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/cypress/psoc64/driver_ppu.c")
+ list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/cypress/psoc64/driver_dap.c")
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/cypress/psoc64/CMSIS_Driver/Driver_USART.c")
embedded_include_directories(PATH "${PLATFORM_DIR}/target/cypress/psoc64/CMSIS_Driver" ABSOLUTE)
embedded_include_directories(PATH "${PLATFORM_DIR}/driver" ABSOLUTE)
diff --git a/platform/ext/target/cypress/psoc64/driver_dap.c b/platform/ext/target/cypress/psoc64/driver_dap.c
new file mode 100644
index 000000000..3b20a7ac1
--- /dev/null
+++ b/platform/ext/target/cypress/psoc64/driver_dap.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdio.h>
+
+#include "driver_dap.h"
+
+#include "cycfg.h"
+#include "cy_device.h"
+#include "cy_device_headers.h"
+#include "cy_ipc_drv.h"
+#include "cy_prot.h"
+#include "cy_sysint.h"
+#include "driver_dap.h"
+#include "pc_config.h"
+
+/* DAPControl SysCall opcode */
+#define DAPCONTROL_SYSCALL_OPCODE (0x3AUL << 24UL)
+
+/* FlashBoot SysCall success return code */
+#define CY_FB_SYSCALL_SUCCESS (0xA0000000UL)
+
+/* SysCall timeout value */
+#define CY_DAP_SYSCALL_WAIT_MAX_TRIES (15000UL)
+
+
+int cy_access_port_control(enum cy_ap_name ap, enum cy_ap_control en)
+{
+ int rc = -1;
+ uint32_t syscallCmd, result;
+ uint32_t timeout = 0U;
+
+ syscallCmd = DAPCONTROL_SYSCALL_OPCODE;
+ syscallCmd |= (uint8_t)en << 16;
+ syscallCmd |= (uint8_t)ap << 8;
+ syscallCmd |= 1;
+
+ /* Get IPC base register address */
+ IPC_STRUCT_Type * ipcStruct = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL);
+
+ while ((CY_IPC_DRV_SUCCESS != Cy_IPC_Drv_LockAcquire(ipcStruct)) &&
+ (timeout < CY_DAP_SYSCALL_WAIT_MAX_TRIES)) {
+ ++timeout;
+ }
+
+ if (timeout < CY_DAP_SYSCALL_WAIT_MAX_TRIES) {
+ timeout = 0U;
+
+ Cy_IPC_Drv_WriteDataValue(ipcStruct, syscallCmd);
+ Cy_IPC_Drv_AcquireNotify(ipcStruct, (1<<CY_IPC_CHAN_SYSCALL));
+
+ while ((Cy_IPC_Drv_IsLockAcquired(ipcStruct))&&
+ (timeout < CY_DAP_SYSCALL_WAIT_MAX_TRIES)) {
+ ++timeout;
+ }
+
+ if (timeout < CY_DAP_SYSCALL_WAIT_MAX_TRIES) {
+ result = Cy_IPC_Drv_ReadDataValue(ipcStruct);
+ if (result != CY_FB_SYSCALL_SUCCESS) {
+ rc = result;
+ }
+ else {
+ rc = 0;
+ }
+ }
+ }
+ return rc;
+}
diff --git a/platform/ext/target/cypress/psoc64/driver_dap.h b/platform/ext/target/cypress/psoc64/driver_dap.h
new file mode 100644
index 000000000..4ad1e65c2
--- /dev/null
+++ b/platform/ext/target/cypress/psoc64/driver_dap.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DRIVER_DAP_H__
+#define __DRIVER_DAP_H__
+
+/** DAPControl SysCall parameter: access port state */
+enum cy_ap_control {
+ CY_AP_DIS = 0,
+ CY_AP_EN = 1
+};
+
+/** DAPControl SysCall parameter: access port name */
+enum cy_ap_name {
+ CY_CM0_AP = 0,
+ CY_CM4_AP = 1,
+ CY_SYS_AP = 2
+};
+
+/* API functions */
+int cy_access_port_control(enum cy_ap_name ap, enum cy_ap_control en);
+
+#endif /* __DRIVER_DAP_H__ */
diff --git a/platform/ext/target/cypress/psoc64/spm_hal.c b/platform/ext/target/cypress/psoc64/spm_hal.c
index 350845a7f..23eb65573 100644
--- a/platform/ext/target/cypress/psoc64/spm_hal.c
+++ b/platform/ext/target/cypress/psoc64/spm_hal.c
@@ -28,6 +28,7 @@
#include "cy_ipc_drv.h"
#include "cy_prot.h"
#include "pc_config.h"
+#include "driver_dap.h"
/* Get address of memory regions to configure MPU */
extern const struct memory_region_limits memory_regions;
@@ -215,6 +216,14 @@ uint32_t tfm_spm_hal_get_ns_entry_point(void)
void tfm_spm_hal_boot_ns_cpu(uintptr_t start_addr)
{
smpu_print_config();
+
+ if (cy_access_port_control(CY_CM4_AP, CY_AP_EN) == 0) {
+ /* The delay is required after Access port was enabled for
+ * debugger/programmer to connect and set TEST BIT */
+ Cy_SysLib_Delay(100);
+ printf("Enabled CM4_AP DAP control\n");
+ }
+
printf("Starting Cortex-M4 at 0x%x\r\n", start_addr);
Cy_SysEnableCM4(start_addr);
}