1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "tde_handle.h"
20 #ifdef HI_BUILD_IN_BOOT
21 #include "hi_go_common.h"
22 #endif
23 #include "tde_define.h"
24 #include "tde_handle.h"
25 #include "osal_list.h"
26
27 hi_handle_mgr *g_tde_handle_list = HI_NULL; /* Manager list of global handle */
28
29 static hi_s32 g_handle = 1;
30 #ifndef HI_BUILD_IN_BOOT
31 static osal_spinlock_t g_handle_lock;
32 #endif
33
tde_get_handle_list(hi_void)34 hi_handle_mgr *tde_get_handle_list(hi_void)
35 {
36 return g_tde_handle_list;
37 }
38
tde_initial_handle(hi_void)39 hi_bool tde_initial_handle(hi_void)
40 {
41 if (g_tde_handle_list == HI_NULL) {
42 #ifndef HI_BUILD_IN_BOOT
43
44 g_tde_handle_list = (hi_handle_mgr *)osal_kmalloc(sizeof(hi_handle_mgr), osal_gfp_kernel);
45
46 #else
47 g_tde_handle_list = (hi_handle_mgr *)HI_GFX_LOGO_Malloc(sizeof(hi_handle_mgr), "tde handle");
48 #endif
49 if (g_tde_handle_list == HI_NULL) {
50 return HI_FALSE;
51 }
52
53 /* Initialize list head */
54 OSAL_INIT_LIST_HEAD(&g_tde_handle_list->header);
55 #ifndef HI_BUILD_IN_BOOT
56 osal_spin_lock_init(&g_tde_handle_list->lock);
57 osal_spin_lock_init(&g_handle_lock);
58 #endif
59 }
60
61 g_handle = 1;
62
63 return HI_TRUE;
64 }
65
tde_get_handle(hi_handle_mgr * res,hi_s32 * handle)66 hi_void tde_get_handle(hi_handle_mgr *res, hi_s32 *handle)
67 {
68 #ifndef HI_BUILD_IN_BOOT
69 unsigned long lockflags;
70 unsigned long handlockflags;
71 #endif
72 if ((res == HI_NULL) || (handle == HI_NULL) || (g_tde_handle_list == HI_NULL)) {
73 return;
74 }
75 tde_spin_lock(&g_handle_lock, handlockflags);
76 /* Jump over unlawful handle */
77 if (g_handle == TDE_MAX_HANDLE_VALUE) {
78 g_handle = 1;
79 }
80 res->handle = g_handle;
81 *handle = g_handle++;
82 tde_spin_unlock(&g_handle_lock, handlockflags);
83 tde_spin_lock(&g_tde_handle_list->lock, lockflags);
84 osal_list_add_tail(&res->header, &g_tde_handle_list->header);
85 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
86 }
87
88 /* To accelerate the speed of find, find form back to front */
tde_query_handle(hi_s32 handle,hi_handle_mgr ** res)89 hi_bool tde_query_handle(hi_s32 handle, hi_handle_mgr **res)
90 {
91 #ifndef HI_BUILD_IN_BOOT
92 unsigned long lockflags;
93 #endif
94 hi_handle_mgr *hdl = HI_NULL;
95 if (res == HI_NULL) {
96 return HI_FAILURE;
97 }
98 if (g_tde_handle_list == HI_NULL) {
99 return HI_FAILURE;
100 }
101 tde_spin_lock(&g_tde_handle_list->lock, lockflags);
102 hdl = osal_list_entry(g_tde_handle_list->header.prev, hi_handle_mgr, header);
103 if (hdl == HI_NULL) {
104 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
105 return HI_FALSE;
106 }
107 while (hdl != g_tde_handle_list) {
108 if (hdl->handle == handle) {
109 *res = hdl;
110 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
111 return HI_TRUE;
112 }
113 hdl = osal_list_entry(hdl->header.prev, hi_handle_mgr, header);
114 if (hdl == HI_NULL) {
115 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
116 return HI_FALSE;
117 }
118 }
119 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
120 return HI_FALSE;
121 }
122
tde_release_handle(hi_s32 handle)123 hi_bool tde_release_handle(hi_s32 handle)
124 {
125 #ifndef HI_BUILD_IN_BOOT
126 unsigned long lockflags;
127 #endif
128 hi_handle_mgr *hdl = HI_NULL;
129 if (g_tde_handle_list == HI_NULL) {
130 return HI_FAILURE;
131 }
132 tde_spin_lock(&g_tde_handle_list->lock, lockflags);
133 hdl = osal_list_entry(g_tde_handle_list->header.next, hi_handle_mgr, header);
134 if (hdl == HI_NULL) {
135 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
136 return HI_FALSE;
137 }
138 while (hdl != g_tde_handle_list) {
139 if (hdl->handle == handle) {
140 osal_list_del_init(&hdl->header);
141 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
142 return HI_TRUE;
143 }
144 hdl = osal_list_entry(hdl->header.next, hi_handle_mgr, header);
145 if (hdl == HI_NULL) {
146 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
147 return HI_FALSE;
148 }
149 }
150 tde_spin_unlock(&g_tde_handle_list->lock, lockflags);
151 return HI_FALSE;
152 }
153
tde_destroy_handle(hi_void)154 hi_void tde_destroy_handle(hi_void)
155 {
156 /* Free head node, note: other nodes are all loaded, their resource are responsibilited by its own module */
157 if (g_tde_handle_list != HI_NULL) {
158 osal_spin_lock_destroy(&g_tde_handle_list->lock);
159 osal_spin_lock_destroy(&g_handle_lock);
160 #ifndef HI_BUILD_IN_BOOT
161 osal_kfree(g_tde_handle_list);
162 #else
163 osal_kfree((HI_CHAR *)g_tde_handle_list);
164 #endif
165
166 g_tde_handle_list = HI_NULL;
167 }
168
169 return;
170 }
171