1 /*
2  * Copyright (c) 2020, Cypress Semiconductor Corporation. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <stdio.h>
17 
18 #include "driver_dap.h"
19 
20 #include "cycfg.h"
21 #include "cy_device.h"
22 #include "cy_device_headers.h"
23 #include "cy_ipc_drv.h"
24 #include "cy_prot.h"
25 #include "cy_sysint.h"
26 #include "driver_dap.h"
27 #include "pc_config.h"
28 
29 /* DAPControl SysCall opcode */
30 #define DAPCONTROL_SYSCALL_OPCODE       (0x3AUL << 24UL)
31 
32 /* FlashBoot SysCall success return code */
33 #define CY_FB_SYSCALL_SUCCESS           (0xA0000000UL)
34 
35 /* SysCall timeout value */
36 #define CY_DAP_SYSCALL_WAIT_MAX_TRIES   (15000UL)
37 
38 
cy_access_port_control(enum cy_ap_name ap,enum cy_ap_control en)39 int cy_access_port_control(enum cy_ap_name ap, enum cy_ap_control en)
40 {
41     int rc = -1;
42     uint32_t syscallCmd, result;
43     uint32_t timeout = 0U;
44 
45     syscallCmd  = DAPCONTROL_SYSCALL_OPCODE;
46     syscallCmd |= (uint8_t)en << 16;
47     syscallCmd |= (uint8_t)ap << 8;
48     syscallCmd |= 1;
49 
50     /* Get IPC base register address */
51     IPC_STRUCT_Type * ipcStruct = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL);
52 
53     while ((CY_IPC_DRV_SUCCESS != Cy_IPC_Drv_LockAcquire(ipcStruct)) &&
54             (timeout < CY_DAP_SYSCALL_WAIT_MAX_TRIES)) {
55         ++timeout;
56     }
57 
58     if (timeout < CY_DAP_SYSCALL_WAIT_MAX_TRIES) {
59         timeout = 0U;
60 
61         Cy_IPC_Drv_WriteDataValue(ipcStruct, syscallCmd);
62         Cy_IPC_Drv_AcquireNotify(ipcStruct, (1<<CY_IPC_CHAN_SYSCALL));
63 
64         while ((Cy_IPC_Drv_IsLockAcquired(ipcStruct))&&
65                 (timeout < CY_DAP_SYSCALL_WAIT_MAX_TRIES)) {
66             ++timeout;
67         }
68 
69         if (timeout < CY_DAP_SYSCALL_WAIT_MAX_TRIES) {
70             result = Cy_IPC_Drv_ReadDataValue(ipcStruct);
71             if (result != CY_FB_SYSCALL_SUCCESS) {
72                 rc = result;
73             }
74             else {
75                 rc = 0;
76             }
77         }
78     }
79     return rc;
80 }
81