ps_sched.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411
  1. /*
  2. * Copyright (c) 2021 Alibaba Group. All rights reserved.
  3. * License-Identifier: Apache-2.0
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  6. * not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include <stdint.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <xtensa/corebits.h>
  23. #include <xtensa/config/core.h>
  24. #include <xtensa/xtruntime.h>
  25. #if HAVE_THREADS_XOS
  26. #include <xtensa/xos.h>
  27. #endif
  28. #include "dsp_ps_debug.h"
  29. #include "vi_hw_api.h"
  30. #include "xrp_api.h"
  31. #include "xrp_dsp_hw.h"
  32. #include "xrp_dsp_user.h"
  33. #include "dsp_ps_ns.h"
  34. #include "csi_dsp_task_defs.h"
  35. #include "csi_dsp_post_process_defs.h"
  36. #include "ps_sched.h"
  37. #include "algo.h"
  38. #include "test_def.h"
  39. #include "dsp_loader.h"
  40. #include "dmaif.h"
  41. #include "dsp_utils.h"
  42. #ifdef DSP_PROFILE_ENBALE
  43. char profile_buf[128*1024];
  44. DSP_PROFILE_CUSTOM_DECLATR(task)
  45. DSP_PROFILE_CUSTOM_DECLATR(algo)
  46. DSP_PROFILE_CUSTOM_DECLATR(intr)
  47. DSP_PROFILE_CUSTOM_DECLATR(cmd)
  48. DSP_PROFILE_CUSTOM_DECLATR(cmdU)
  49. #endif
  50. #define PS_CRITICAL_SECTION __attribute__((section(".dram0.data")))
  51. s_schduler_t g_scheduler PS_CRITICAL_SECTION;
  52. volatile char g_task_rdy_grp PS_CRITICAL_SECTION;
  53. volatile char g_task_rdy_Tbl[8] PS_CRITICAL_SECTION;
  54. int __stack_size = 0x1400;
  55. char task_ummap[256] PS_CRITICAL_SECTION =
  56. {
  57. 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  58. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  59. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  60. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  61. 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  62. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  63. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  64. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  65. 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  66. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  67. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  68. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  69. 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  70. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  71. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  72. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
  73. };
  74. dsp_task_t task_table[PS_MAX_TASK_TYPE] PS_CRITICAL_SECTION={
  75. {0 , CSI_DSP_TASK_HW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,NULL,0},NULL,NULL,NULL,NULL},
  76. {1 , CSI_DSP_TASK_HW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,NULL,0},NULL,NULL,NULL,NULL},
  77. {2 , CSI_DSP_TASK_HW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  78. {3 , CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,XRP_PS_NSID_COMMON_CMD,{0,0,0},NULL,NULL,NULL,NULL},
  79. {4 , CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  80. {5 , CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  81. {6 , CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  82. {7 , CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  83. {8 , CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  84. {9 , CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  85. {10, CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  86. {11, CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  87. {12, CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  88. {13, CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  89. {14, CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL},
  90. {15, CSI_DSP_TASK_SW, DSP_TASK_STATUS_FREE, {CSI_DSP_FE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{CSI_DSP_BE_TYPE_INVALID,-1,NULL,NULL,NULL,NULL},{0,NULL,NULL,NULL},NULL,NULL,{0,0,0},NULL,NULL,NULL,NULL}
  91. };
  92. #define EXTRA_REPORT_SIZE 128
  93. char extra_report[EXTRA_REPORT_SIZE] PS_CRITICAL_SECTION;
  94. static csi_dsp_extra_param_t extra_param PS_CRITICAL_SECTION ={
  95. .report_buf = (uint32_t)&extra_report,
  96. .report_buf_size = EXTRA_REPORT_SIZE,
  97. };
  98. static csi_dsp_algo_param_t g_sw_algo_par;
  99. static inline void set_ready_task(uint8_t pri)
  100. {
  101. uint8_t lsb = pri&0x7;
  102. uint8_t msb = pri>>3&0x7;
  103. uint32_t intstate=XTOS_DISABLE_INTERRUPTS();
  104. g_task_rdy_Tbl[msb]|=0x1<<lsb;
  105. g_task_rdy_grp |=0x1<<msb;
  106. XTOS_RESTORE_INTERRUPTS(intstate);
  107. }
  108. static inline void clr_ready_task(uint8_t pri,bool (*is_done)())
  109. {
  110. uint8_t lsb = pri&0x7;
  111. uint8_t msb = pri>>3&0x7;
  112. uint32_t intstate=XTOS_DISABLE_INTERRUPTS();
  113. if(is_done!=NULL && is_done()!=TTRUE)
  114. {
  115. XTOS_RESTORE_INTERRUPTS(intstate);
  116. return;
  117. }
  118. g_task_rdy_Tbl[msb]&=~(0x1<<lsb);
  119. if(g_task_rdy_Tbl[msb]==0)
  120. {
  121. g_task_rdy_grp &=~(0X1<<msb);
  122. }
  123. XTOS_RESTORE_INTERRUPTS(intstate);
  124. }
  125. static inline dsp_task_t* get_ready_task()
  126. {
  127. uint8_t msb = task_ummap[g_task_rdy_grp];
  128. uint8_t lsb= task_ummap[g_task_rdy_Tbl[msb]];
  129. return &task_table[msb<<3|lsb];
  130. }
  131. static void
  132. ps_task_trigger_intr_handler(void * arg)
  133. {
  134. int32_t pri = (int32_t)arg;
  135. DSP_PROFILE_CUSTOM_ID_ADD(intr,pri)
  136. DSP_PROFILE_CUSTOM_START(intr)
  137. task_table[pri].intr_handler(task_table[pri].intr_arg);
  138. set_ready_task(pri);
  139. DSP_PROFILE_CUSTOM_END(intr)
  140. }
  141. static inline dsp_task_t* get_free_sw_task()
  142. {
  143. int task_num= PS_MAX_TASK_TYPE;
  144. int id;
  145. for(id=0;id<task_num;id++)
  146. {
  147. if(task_table[id].type&CSI_DSP_TASK_SW && task_table[id].status == DSP_TASK_STATUS_FREE)
  148. {
  149. return &task_table[id];
  150. }
  151. }
  152. return NULL;
  153. }
  154. static inline dsp_task_t* get_free_hw_task()
  155. {
  156. int task_num= PS_MAX_TASK_TYPE;
  157. int id;
  158. for(id=0;id<task_num;id++)
  159. {
  160. if(task_table[id].type&CSI_DSP_TASK_HW && task_table[id].status == DSP_TASK_STATUS_FREE)
  161. {
  162. return &task_table[id];
  163. }
  164. }
  165. return NULL;
  166. }
  167. static inline int release_task(dsp_task_t* task)
  168. {
  169. task->status = DSP_TASK_STATUS_FREE;
  170. return 0;
  171. }
  172. static int allocte_ns_id(int task_id,unsigned char *ns_id)
  173. {
  174. unsigned char base_id[]=XRP_PS_NSID_COMMON_CMD;
  175. int i;
  176. for(i=0;i<XRP_NAMESPACE_ID_SIZE;i++)
  177. {
  178. ns_id[i]=base_id[i]+(char)task_id;
  179. }
  180. return 0;
  181. }
  182. static int dsp_get_latest_hw_task(uint16_t pri,uint32_t intnum)
  183. {
  184. int task_num= PS_MAX_TASK_TYPE;
  185. int id;
  186. for(id=0;id<task_num;id++)
  187. {
  188. if(pri!=id && task_table[id].type&CSI_DSP_TASK_HW && task_table[id].status == DSP_TASK_STATUS_RUNING)
  189. {
  190. if(task_table[id].irq_num == intnum)
  191. {
  192. return id;
  193. }
  194. }
  195. }
  196. return -1;
  197. }
  198. int ps_task_interrupt_register(uint16_t pri,uint32_t intrnum)
  199. {
  200. int32_t ret = 0;
  201. void (*old_intr_handler)(void *data);
  202. uint32_t task_priority = (uint32_t )pri;
  203. // Normally none of these calls should fail. We don't check them
  204. // individually, any one failing will cause this function to return failure.
  205. ret = xtos_set_interrupt_handler(intrnum,
  206. ps_task_trigger_intr_handler, (void *)task_priority, &old_intr_handler);
  207. if(old_intr_handler==NULL)
  208. {
  209. ps_err("previous interrupt(%d) hander is NULL\n",intrnum);
  210. return -1;
  211. }
  212. if(old_intr_handler == ps_task_trigger_intr_handler)
  213. {
  214. task_table[task_priority].intr_arg = (void*)dsp_get_latest_hw_task(task_priority,intrnum);
  215. if((int)task_table[pri].intr_arg == -1)
  216. {
  217. ps_err("add task on hw init fail, pri:%d,intr_num:%d\n",task_priority,intrnum);
  218. }
  219. }
  220. else
  221. {
  222. task_table[task_priority].intr_arg = (void*)-1;
  223. }
  224. task_table[pri].intr_handler = old_intr_handler;
  225. xtos_interrupt_enable(intrnum);
  226. // ret += xtos_interrupt_enable(intrnum);
  227. ps_debug("register interrupt:%d to ps interrupt handler %s\n",intrnum,ret==0?"success":"fail");
  228. return ret;
  229. }
  230. int ps_task_interrupt_disable(uint16_t pri,uint32_t intrnum)
  231. {
  232. int32_t ret = 0;
  233. void (*old_intr_handler)(void *data);
  234. uint32_t task_priority = pri;
  235. // Normally none of these calls should fail. We don't check them
  236. // individually, any one failing will cause this function to return failure.
  237. ret = xtos_set_interrupt_handler(intrnum,
  238. task_table[pri].intr_handler, (void *)task_priority, &old_intr_handler);
  239. xtos_interrupt_disable(intrnum);
  240. ps_debug("disable task %d,interrupt\n",task_priority);
  241. return ret;
  242. }
  243. static inline dsp_task_t * ps_search_task_by_ns(unsigned char* nsid)
  244. {
  245. int loop;
  246. for(loop=0;loop<g_scheduler.task_num;loop++)
  247. {
  248. if(memcmp(nsid,g_scheduler.task_handler[loop]->nsid,XRP_NAMESPACE_ID_SIZE)==0)
  249. {
  250. return g_scheduler.task_handler[loop];
  251. }
  252. }
  253. return NULL;
  254. }
  255. static inline dsp_task_t *dsp_search_task_by_id(int id)
  256. {
  257. if(id>=PS_MAX_TASK_TYPE)
  258. {
  259. return NULL;
  260. }
  261. return g_scheduler.task_handler[id];
  262. }
  263. int ps_task_interrupt_register_nsid(unsigned char* nsid)
  264. {
  265. dsp_task_t * task =ps_search_task_by_ns(nsid);
  266. if(NULL==task)
  267. {
  268. ps_err("Nsid register fail\n");
  269. return -1;
  270. }
  271. return ps_task_interrupt_register(task->prio,task->irq_num);
  272. }
  273. int ps_task_enable_common_task()
  274. {
  275. unsigned char ns_id[]=XRP_PS_NSID_COMMON_CMD;
  276. if(ps_task_interrupt_register_nsid(ns_id))
  277. {
  278. ps_debug("fail to regster the common int\n");
  279. return -1;
  280. }
  281. xrp_interrupt_on();
  282. ps_debug("xrp command irq enable\n");
  283. return 0;
  284. }
  285. static enum task_result ps_idle_task(void* context)
  286. {
  287. XT_WAITI(0);
  288. return PS_TASK_SUCCESS;
  289. }
  290. static bool ps_is_idle_task_done(void* context)
  291. {
  292. return TFALSE;
  293. }
  294. extern int idma_inition();
  295. int init_scheduler(struct xrp_device *device)
  296. {
  297. int index;
  298. int common_task_flag =0;
  299. int task_num= sizeof(task_table)/sizeof(dsp_task_t);
  300. char common_id[]=XRP_PS_NSID_COMMON_CMD;
  301. memset((void*)&g_scheduler.task_handler,0x0,sizeof(g_scheduler.task_handler));
  302. g_scheduler.task_num=0;
  303. g_scheduler.device=device;
  304. if(task_num==0|task_num>PS_MAX_TASK_TYPE)
  305. {
  306. ps_err("task Initialize fail , task num :(%d) Error\n",task_num);
  307. return -1;
  308. }
  309. for(index=0;index<task_num;index++)
  310. {
  311. /*********The first SW task as common cmd task */
  312. if(common_task_flag==0&& task_table[index].type == CSI_DSP_TASK_SW)
  313. {
  314. memcpy(task_table[index].nsid,common_id,XRP_NAMESPACE_ID_SIZE);
  315. task_table[index].task_pro = ps_process_xrp_task;
  316. task_table[index].report_info.buf=NULL;
  317. task_table[index].report_info.buf_size=0;
  318. task_table[index].report_info.report_id=-1;
  319. task_table[index].irq_num = xrp_get_irq();
  320. if(0!=ps_register_cmd_handler(task_table[index].nsid,ps_common_command,NULL))
  321. {
  322. ps_err("Common task register fail\n");
  323. return -1;
  324. }
  325. g_scheduler.task_handler[g_scheduler.task_num++]=&task_table[index];
  326. task_table[index].status=DSP_TASK_STATUS_IDEL;
  327. common_task_flag = 1;
  328. }
  329. else
  330. {
  331. //g_scheduler.task_handler[task_table[index].prio] = &task_table[index];
  332. task_table[index].status=DSP_TASK_STATUS_FREE;
  333. }
  334. }
  335. /**the clear task schdule table***************/
  336. g_task_rdy_grp=0;
  337. memset((void*)&g_task_rdy_Tbl,0x0,sizeof(g_task_rdy_Tbl));
  338. /**the last task reigters as idle task*/
  339. dsp_task_t *idle_task = &task_table[task_num-1];
  340. idle_task->task_pro = ps_idle_task;
  341. idle_task->task_empty_check = ps_is_idle_task_done;
  342. idle_task->status = DSP_TASK_STATUS_IDEL;
  343. g_scheduler.task_handler[g_scheduler.task_num++]=idle_task;
  344. set_ready_task(idle_task->prio);
  345. #if 0
  346. // idma_inition();
  347. #else
  348. TMDMA* idma_obj =dmaif_getDMACtrl();
  349. idma_obj->init();
  350. #endif
  351. sw_be_init();
  352. #ifdef DSP_PROFILE_ENBALE
  353. dsp_profile_init(profile_buf,sizeof(profile_buf));
  354. #endif
  355. return 0;
  356. }
  357. static int dsp_search_higher_prio_task(dsp_task_t *task)
  358. {
  359. int loop=0;
  360. dsp_task_t *task_temp=NULL;
  361. for(loop=0;loop<g_scheduler.task_num;loop++)
  362. {
  363. task_temp = g_scheduler.task_handler[loop];
  364. if(task_temp!=NULL && task_temp!=task)
  365. {
  366. if(task_temp->task_fe.type == task->task_fe.type&&
  367. task_temp->prio<task->prio)
  368. {
  369. return task_temp->prio;
  370. }
  371. }
  372. }
  373. return -1;
  374. }
  375. static int dsp_add_task_to_scheduler(dsp_task_t* task)
  376. {
  377. int loop=0;
  378. if(g_scheduler.task_num>=PS_MAX_TASK_TYPE)
  379. {
  380. for(loop=0;loop<g_scheduler.task_num;loop++)
  381. {
  382. if(g_scheduler.task_handler[loop]==NULL)
  383. {
  384. g_scheduler.task_handler[loop]=task;
  385. return loop;
  386. }
  387. }
  388. return -1;
  389. }
  390. g_scheduler.task_handler[g_scheduler.task_num]=task;
  391. return g_scheduler.task_num++;
  392. }
  393. static void dsp_remove_task_from_scheduler(int task_id)
  394. {
  395. if(g_scheduler.task_num == (task_id+1))
  396. {
  397. g_scheduler.task_num--;
  398. }
  399. g_scheduler.task_handler[task_id]=NULL;
  400. }
  401. enum xrp_status ps_register_report_to_task(void *context)
  402. {
  403. struct report_config_msg *msg= (struct report_config_msg *)context;
  404. // dsp_task_t * task =ps_search_task_by_ns(msg->task);
  405. dsp_task_t * task = dsp_search_task_by_id(msg->report_id); //report_id equal to task -id;
  406. if(NULL==task)
  407. {
  408. ps_err("Nsid register fail\n");
  409. return XRP_STATUS_FAILURE;
  410. }
  411. if(msg->report_id <0)
  412. {
  413. ps_err("report_id %d invalid\n",msg->report_id);
  414. return XRP_STATUS_FAILURE;
  415. }
  416. switch(msg->flag)
  417. {
  418. case CMD_SETUP:
  419. if(XRP_STATUS_SUCCESS
  420. !=xrp_get_report_buffer(g_scheduler.device,&task->report_info.buf,&task->report_info.buf_size))
  421. {
  422. ps_err("report get xrp buffer fail\n");
  423. return XRP_STATUS_FAILURE;
  424. }
  425. if(task->report_info.buf_size < msg->size)
  426. {
  427. ps_err("report %d request size :%d, exceed the limit:%d",msg->report_id,msg->size,task->report_info.buf_size);
  428. return XRP_STATUS_FAILURE;
  429. }
  430. task->report_info.buf_size = msg->size;
  431. task->report_info.report_id = msg->report_id;
  432. break;
  433. case CMD_RELEASE:
  434. task->report_info.report_id=-1;
  435. break;
  436. default:
  437. return XRP_STATUS_FAILURE;
  438. }
  439. ps_debug("task %d, register report:%d,report_buf:%x\n",task->nsid[0],task->report_info.report_id,task->report_info.buf);
  440. return XRP_STATUS_SUCCESS;
  441. }
  442. enum xrp_status ps_run_data_move_cmd(void *context)
  443. {
  444. struct data_move_msg *msg= (struct data_move_msg *)context;
  445. ps_debug("src :%llx,dst:%llx,size:%d\n",msg->src_addr, msg->dst_addr, msg->size);
  446. // if(idma_copy_ext2ext(msg->src_addr, msg->dst_addr, msg->size,
  447. // image_in_char_tdma0,51200))
  448. // {
  449. // return XRP_STATUS_FAILURE;
  450. // }
  451. ps_debug("success\n");
  452. return XRP_STATUS_SUCCESS;
  453. }
  454. //enum xrp_status dsp_dummy_algo(csi_dsp_algo_param_t* param)
  455. //{
  456. // if(!param || param->buffer_num <2 )
  457. // {
  458. // return XRP_STATUS_FAILURE;
  459. // }
  460. // struct csi_dsp_buffer *bufs;
  461. // if(idma_copy_ext2ext(bufs[0].planes[0].buf_phy, bufs[1].planes[0].buf_phy,bufs[0].planes[0].size,
  462. // image_in_char_tdma0,61440))
  463. // {
  464. // return XRP_STATUS_FAILURE;
  465. // }
  466. // return XRP_STATUS_SUCCESS;
  467. //
  468. //}
  469. static inline void fill_hw_task_algo_param(csi_dsp_algo_param_t* param,entry_struct_t* in_info,
  470. struct csi_dsp_buffer * out_info)
  471. {
  472. struct csi_dsp_buffer *bufs;
  473. if(!param||!in_info||!out_info)
  474. return;
  475. if(param->buffer_num <2)
  476. {
  477. return;
  478. }
  479. bufs =(struct csi_dsp_buffer *) param->buffer_struct_ptr;
  480. bufs[0].height= in_info->height;
  481. bufs[0].width = in_info->width;
  482. bufs[0].plane_count =1;
  483. bufs[0].planes[0].buf_phy=in_info->pBuff;
  484. bufs[0].planes[0].stride = in_info->pitch;
  485. bufs[0].planes[0].size = in_info->height*in_info->pitch;
  486. if(in_info->height == in_info->frame_height)
  487. {
  488. param->extra_param_ptr->start_line =0;
  489. param->extra_param_ptr->end_line =0;
  490. param->extra_param_ptr->total_line =0;
  491. }
  492. else
  493. {
  494. param->extra_param_ptr->start_line = in_info->y;
  495. param->extra_param_ptr->end_line = in_info->y+in_info->height;
  496. param->extra_param_ptr->total_line = in_info->frame_height;
  497. }
  498. // if(in_info->meta)
  499. {
  500. param->extra_param_ptr->frame_meta.temp_projector = in_info->meta.temp_projector;
  501. param->extra_param_ptr->frame_meta.temp_sensor = in_info->meta.temp_sensor;
  502. param->extra_param_ptr->frame_meta.frame_id = in_info->meta.frame_id;
  503. param->extra_param_ptr->frame_meta.timestap = in_info->meta.timestap;
  504. }
  505. bufs[1].height= out_info->height;
  506. bufs[1].width = out_info->width;
  507. bufs[1].format = out_info->format;
  508. bufs[1].plane_count =out_info->plane_count;
  509. memcpy(bufs[1].planes,out_info->planes,sizeof(struct csi_dsp_plane)*out_info->plane_count);
  510. }
  511. static inline int fill_sw_task_algo_param(csi_dsp_algo_param_t* param,const void *in_data,
  512. struct xrp_buffer_group *buffer_group,entry_struct_t * out_info)
  513. {
  514. struct csi_sw_task_req *req = (struct csi_sw_task_req *)in_data;
  515. int buf_idx;
  516. struct csi_dsp_buffer *buf;
  517. if(!param || !in_data)
  518. {
  519. return CSI_DSP_ERR_ILLEGAL_PARAM;
  520. }
  521. param->buffer_struct_ptr = &req->buffers[0];
  522. param->buffer_num = req->buffer_num;
  523. param->set_buf_ptr = (void*)req->sett_ptr;
  524. param->set_buf_size = req->sett_length;
  525. param->extra_param_ptr = NULL;
  526. if(out_info)
  527. {
  528. buf_idx = req->buffer_num-1;
  529. buf = &req->buffers[buf_idx];
  530. if(buf->type != CSI_DSP_BUF_ALLOC_FM)
  531. {
  532. return CSI_DSP_BUF_TYPE_ERR;
  533. }
  534. buf->format = out_info->fmt;
  535. buf->height = out_info->height;
  536. buf->width = out_info->width;
  537. buf->plane_count = 1;
  538. buf->planes[0].buf_phy = out_info->pBuff;
  539. buf->planes[0].stride = out_info->pitch;
  540. }
  541. return CSI_DSP_OK;
  542. }
  543. static inline enum xrp_status dsp_process_sw_task(void *context,
  544. const void *in_data, size_t in_data_size,
  545. void *out_data, size_t out_data_size,
  546. struct xrp_buffer_group *buffer_group)
  547. {
  548. dsp_task_t *task = (dsp_task_t *)context;
  549. entry_struct_t ctrl_info;
  550. // csi_dsp_algo_param_t param;
  551. //
  552. // task->task_algo.param =&param;
  553. if(task->type == CSI_DSP_TASK_SW_TO_HW)
  554. {
  555. task->task_be.get_next_entry(task->task_be.id,&ctrl_info);
  556. fill_sw_task_algo_param(task->task_algo.param,in_data,buffer_group,&ctrl_info);
  557. }
  558. else
  559. {
  560. fill_sw_task_algo_param(task->task_algo.param,in_data,buffer_group,NULL);
  561. }
  562. if(!task->task_algo.algo_process)
  563. {
  564. *((csi_dsp_status_e *)out_data) = CSI_DSP_ALGO_INVALID;
  565. return XRP_STATUS_SUCCESS;
  566. }
  567. DSP_PROFILE_CUSTOM_START(algo)
  568. if(XRP_STATUS_SUCCESS !=task->task_algo.algo_process(task->task_algo.param))
  569. {
  570. *((csi_dsp_status_e *)out_data) = CSI_DSP_ALGO_ERR;
  571. return XRP_STATUS_SUCCESS;
  572. }
  573. DSP_PROFILE_CUSTOM_END(algo)
  574. if(task->type == CSI_DSP_TASK_SW_TO_HW)
  575. {
  576. if(task->task_be.get_state(task->task_be.id)!= 0)
  577. {
  578. *((csi_dsp_status_e *)out_data) = CSI_DSP_ALGO_ERR;
  579. }
  580. task->task_be.entry_start(task->task_be.id,&ctrl_info);
  581. }
  582. return XRP_STATUS_SUCCESS;
  583. }
  584. static enum task_result dsp_process_hw_task(void* context)
  585. {
  586. dsp_task_t *task = (dsp_task_t *)context;
  587. entry_struct_t in_info;
  588. struct csi_dsp_buffer out_info;
  589. task->task_algo.param->extra_param_ptr = &extra_param;
  590. task->task_algo.param->extra_param_ptr->report_size = 0;
  591. if(task->task_fe.get_next_entry(task->task_fe.id, &in_info))
  592. {
  593. if(task->task_fe.get_state(task->task_fe.id)==EHW_ERROR_OVER_FLOW)
  594. {
  595. task->task_fe.update_state(task->task_fe.id);
  596. task->task_be.update_state(task->task_be.id);
  597. }
  598. if(task->task_fe.get_state(task->task_fe.id)==EHW_RECOVERYING && task->task_be.get_state(task->task_be.id)==EHW_RECOVERY_DONE)
  599. {
  600. task->task_fe.update_state(task->task_fe.id);
  601. task->task_be.update_state(task->task_be.id);
  602. if(task->report_info.buf)
  603. {
  604. ps_fill_report(task->report_info.buf,CSI_DSP_HW_FRAME_DROP,NULL,0);
  605. }
  606. return PS_TASK_FAILURE_WITH_REPORT;
  607. }
  608. return PS_TASK_FAILURE;
  609. }
  610. #if 0
  611. static uint8_t side=0;
  612. /*********************/
  613. if(in_info.y ==0)
  614. {
  615. side ^=1;
  616. }
  617. if(side == 0 && in_info.y >120)
  618. {
  619. return PS_TASK_SUCCESS;
  620. }
  621. #endif
  622. if(task->task_be.get_next_entry(task->task_be.id,&out_info))
  623. {
  624. if(task->type == CSI_DSP_TASK_HW_TO_SW)
  625. {
  626. /**for back end issue such as no variable buffer drop the coming entry **/
  627. task->task_fe.entry_done(task->task_fe.id,&in_info);
  628. ps_wrn("be get entry fail\n");
  629. }
  630. return PS_TASK_FAILURE;
  631. }
  632. /***************************to pack the algo param******************************/
  633. fill_hw_task_algo_param(task->task_algo.param,&in_info,&out_info);
  634. if(task->task_algo.algo_process == NULL)
  635. {
  636. return PS_TASK_FAILURE;
  637. }
  638. DSP_PROFILE_CUSTOM_START(algo)
  639. if(XRP_STATUS_FAILURE ==task->task_algo.algo_process(task->task_algo.param))
  640. {
  641. // *((csi_dsp_status_e*)out_data) = CSI_DSP_ALGO_ERR;
  642. ps_wrn("Algo run fail\n");
  643. return PS_TASK_FAILURE;
  644. }
  645. DSP_PROFILE_CUSTOM_END(algo)
  646. task->task_fe.entry_done(task->task_fe.id,&in_info);
  647. if(task->task_fe.get_state(task->task_fe.id)!= 0)
  648. {
  649. ps_wrn("Fe Error\n");
  650. return PS_TASK_FAILURE;
  651. }
  652. if(task->task_be.entry_start(task->task_be.id,&out_info))
  653. {
  654. if(task->task_be.get_state(task->task_be.id) < 0)
  655. {
  656. return PS_TASK_FAILURE_WITH_REPORT;
  657. }
  658. ps_wrn("Be trigger fail\n");
  659. return PS_TASK_FAILURE;
  660. }
  661. if(task->type == CSI_DSP_TASK_HW_TO_SW)
  662. {
  663. csi_dsp_result_report(task->report_info.buf,(void*)&out_info,sizeof(out_info),(void*)extra_param.report_buf,extra_param.report_size);
  664. return PS_TASK_SUCCESS_WITH_REPORT;
  665. }
  666. return PS_TASK_SUCCESS;
  667. }
  668. static enum xrp_status ps_create_task(void *req,void * resp)
  669. {
  670. struct csi_dsp_task_create_req *msg= (struct csi_dsp_task_create_req *)req;
  671. struct csi_dsp_task_create_resp *reps_msg= (struct csi_dsp_task_create_resp *)resp;
  672. dsp_task_t* new_task;
  673. int task_id =-1;
  674. enum xrp_status status;
  675. ps_debug("Task type %d to create\n",msg->type);
  676. switch(msg->type)
  677. {
  678. case CSI_DSP_TASK_SW:
  679. case CSI_DSP_TASK_SW_TO_SW:
  680. case CSI_DSP_TASK_SW_TO_HW:
  681. new_task = get_free_sw_task();
  682. if(!new_task)
  683. {
  684. reps_msg->status = CSI_DSP_TASK_ALLOC_FAIL;
  685. return XRP_STATUS_SUCCESS;
  686. }
  687. allocte_ns_id(new_task->prio,new_task->nsid);
  688. xrp_device_register_namespace(g_scheduler.device,new_task->nsid,dsp_process_sw_task, new_task, &status);
  689. if(status!=XRP_STATUS_SUCCESS)
  690. {
  691. reps_msg->status = CSI_DSP_TASK_ALLOC_FAIL;
  692. return XRP_STATUS_SUCCESS;
  693. }
  694. break;
  695. case CSI_DSP_TASK_HW:
  696. case CSI_DSP_TASK_HW_TO_SW:
  697. case CSI_DSP_TASK_HW_TO_HW:
  698. new_task = get_free_hw_task();
  699. if(!new_task)
  700. {
  701. reps_msg->status = CSI_DSP_TASK_ALLOC_FAIL;
  702. return XRP_STATUS_SUCCESS;
  703. }
  704. allocte_ns_id(new_task->prio,new_task->nsid);
  705. new_task->task_pro = dsp_process_hw_task;
  706. break;
  707. default:
  708. reps_msg->status =CSI_DSP_ERR_ILLEGAL_PARAM;
  709. return XRP_STATUS_SUCCESS;
  710. }
  711. if(msg->type == CSI_DSP_TASK_SW_TO_SW)
  712. {
  713. new_task->status = DSP_TASK_STATUS_READY;
  714. }
  715. else
  716. {
  717. new_task->status = DSP_TASK_STATUS_IDEL;
  718. }
  719. new_task->type = msg->type;
  720. new_task->report_info.buf=NULL;
  721. new_task->report_info.buf_size=0;
  722. new_task->report_info.report_id=-1;
  723. new_task->task_fe.type= CSI_DSP_FE_TYPE_INVALID;
  724. new_task->task_be.type= CSI_DSP_BE_TYPE_INVALID;
  725. new_task->task_algo.algo_id=-1;
  726. new_task->task_algo.param = NULL;
  727. // g_scheduler.task_handler[task_id]=new_task;
  728. task_id = dsp_add_task_to_scheduler(new_task);
  729. if(task_id <0)
  730. {
  731. reps_msg->status = CSI_DSP_TASK_ADD_TO_SCHEDULER_FAIL;
  732. release_task(new_task);
  733. return XRP_STATUS_SUCCESS;
  734. }
  735. reps_msg->status = CSI_DSP_OK;
  736. reps_msg->task_id = task_id;
  737. // g_scheduler.task_num++;
  738. memcpy(reps_msg->task_ns,new_task->nsid,XRP_NAMESPACE_ID_SIZE);
  739. return XRP_STATUS_SUCCESS;
  740. }
  741. static enum xrp_status ps_destroy_task(void *req,void * resp)
  742. {
  743. struct csi_dsp_task_free_req *msg = (struct csi_dsp_task_free_req*)req;
  744. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  745. reps_msg->status = CSI_DSP_OK;
  746. enum xrp_status status;
  747. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  748. if(!task)
  749. {
  750. reps_msg->status = CSI_DSP_TASK_NOT_VALID;
  751. return XRP_STATUS_SUCCESS;
  752. }
  753. dsp_remove_task_from_scheduler(msg->task_id);
  754. if(task->task_algo.param)
  755. {
  756. if(CSI_DSP_TASK_HW & task->type)
  757. {
  758. if(task->task_algo.param->buffer_struct_ptr)
  759. free(task->task_algo.param->buffer_struct_ptr);
  760. if(task->task_algo.param->set_buf_ptr)
  761. free(task->task_algo.param->set_buf_ptr);
  762. }
  763. free(task->task_algo.param);
  764. }
  765. task->task_algo.param = NULL;
  766. task->task_algo.algo_id =-1;
  767. task->task_algo.algo_process = NULL;
  768. if(CSI_DSP_TASK_SW & task->type)
  769. {
  770. xrp_device_unregister_namespace(g_scheduler.device,task->nsid,&status);
  771. }
  772. release_task(task);
  773. reps_msg->status = CSI_DSP_OK;
  774. return XRP_STATUS_SUCCESS;
  775. }
  776. static enum xrp_status dsp_task_start(void *req,void * resp){
  777. struct csi_dsp_task_start_req *msg= (struct csi_dsp_task_start_req *)req;
  778. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  779. ps_debug("task %d to start\n",msg->task_id);
  780. dsp_task_t *task = dsp_search_task_by_id(msg->task_id);
  781. if(task == NULL)
  782. {
  783. reps_msg->status = CSI_DSP_ERR_ILLEGAL_PARAM;
  784. return XRP_STATUS_SUCCESS;
  785. }
  786. if(task->status == DSP_TASK_STATUS_RUNING)
  787. {
  788. reps_msg->status = CSI_DSP_TASK_ALREADY_RUNNING;
  789. return XRP_STATUS_SUCCESS;
  790. }
  791. else if(task->status ==DSP_TASK_STATUS_READY)
  792. {
  793. /*TODO enable task.. enable the HW INIT */
  794. if(0!=ps_task_interrupt_register(task->prio,task->irq_num))
  795. {
  796. return XRP_STATUS_FAILURE;
  797. }
  798. task->status = DSP_TASK_STATUS_RUNING;
  799. reps_msg->status = CSI_DSP_OK;
  800. return XRP_STATUS_SUCCESS;
  801. }
  802. else
  803. {
  804. reps_msg->status = CSI_DSP_TASK_START_FAIL;
  805. return XRP_STATUS_SUCCESS;
  806. }
  807. }
  808. static enum xrp_status dsp_task_stop(void *req,void * resp){
  809. struct csi_dsp_task_start_req *msg= (struct csi_dsp_task_start_req *)req;
  810. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  811. ps_debug("task %d to stop\n",msg->task_id);
  812. dsp_task_t *task = dsp_search_task_by_id(msg->task_id);
  813. reps_msg->status = CSI_DSP_OK;
  814. if(task == NULL)
  815. {
  816. reps_msg->status = CSI_DSP_ERR_ILLEGAL_PARAM;
  817. return XRP_STATUS_SUCCESS;
  818. }
  819. if(task->status == DSP_TASK_STATUS_RUNING)
  820. {
  821. ps_task_interrupt_disable(task->prio,task->irq_num);
  822. task->status = DSP_TASK_STATUS_READY;
  823. return XRP_STATUS_SUCCESS;
  824. }
  825. else
  826. {
  827. return XRP_STATUS_SUCCESS;
  828. }
  829. }
  830. static inline void update_task_status(dsp_task_t * task )
  831. {
  832. switch(task->type)
  833. {
  834. case CSI_DSP_TASK_SW_TO_HW:
  835. if((task->status == DSP_TASK_STATUS_IDEL) &&
  836. (task->task_be.type!=CSI_DSP_BE_TYPE_INVALID) &&
  837. (task->task_algo.algo_process!=NULL))
  838. {
  839. task->status= DSP_TASK_STATUS_READY;
  840. }
  841. break;
  842. case CSI_DSP_TASK_HW_TO_SW:
  843. if((task->status == DSP_TASK_STATUS_IDEL) &&
  844. (task->task_fe.type!=CSI_DSP_FE_TYPE_INVALID) &&
  845. (task->task_be.type!=CSI_DSP_BE_TYPE_INVALID)&&
  846. (task->task_algo.algo_process!=NULL))
  847. {
  848. task->status= DSP_TASK_STATUS_READY;
  849. }
  850. break;
  851. case CSI_DSP_TASK_HW_TO_HW:
  852. if((task->status == DSP_TASK_STATUS_IDEL) &&
  853. (task->task_fe.type!=CSI_DSP_FE_TYPE_INVALID) &&
  854. (task->task_be.type!=CSI_DSP_BE_TYPE_INVALID)&&
  855. (task->task_algo.algo_process!=NULL))
  856. {
  857. task->status= DSP_TASK_STATUS_READY;
  858. }
  859. break;
  860. default:
  861. break;
  862. }
  863. }
  864. int high_pri_task =-1;
  865. static bool dsp_vipre_task_check()
  866. {
  867. if( ps_is_vipre_task_empty()== true || high_pri_task<0 )
  868. {
  869. return true;
  870. }
  871. set_ready_task(high_pri_task);
  872. return false;
  873. }
  874. static enum xrp_status dsp_task_fe_config(void *req,void * resp){
  875. struct csi_dsp_task_fe_para *msg= (struct csi_dsp_task_fe_para *)req;
  876. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  877. reps_msg->status = CSI_DSP_OK;
  878. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  879. if(!task)
  880. {
  881. reps_msg->status = CSI_DSP_TASK_NOT_VALID;
  882. return XRP_STATUS_SUCCESS;
  883. }
  884. ps_debug("FE %d to config\n",msg->frontend_type);
  885. switch(msg->frontend_type)
  886. {
  887. case CSI_DSP_FE_TYPE_CPU:
  888. break;
  889. case CSI_DSP_FE_TYPE_ISP:
  890. if(XRP_STATUS_SUCCESS!=ps_isp_config_message_handler((void*)&msg->isp_param,(void*)&task->task_fe))
  891. {
  892. reps_msg->status = CSI_DSP_FE_CONFIG_FAIL;
  893. return XRP_STATUS_SUCCESS;
  894. }
  895. task->irq_num = ps_get_isp_irq(msg->isp_param.id);
  896. break;
  897. case CSI_DSP_FE_TYPE_VIPRE:
  898. if(XRP_STATUS_SUCCESS!=ps_vipre_config_message_handler((void*)&msg->isp_param,(void*)&task->task_fe))
  899. {
  900. reps_msg->status = CSI_DSP_FE_CONFIG_FAIL;
  901. return XRP_STATUS_SUCCESS;
  902. }
  903. task->irq_num = ps_get_vipre_irq();
  904. high_pri_task = dsp_search_higher_prio_task(task);
  905. if(high_pri_task >=0)
  906. {
  907. task->task_empty_check = dsp_vipre_task_check;
  908. }
  909. else
  910. {
  911. task->task_empty_check = NULL;
  912. }
  913. break;
  914. default:
  915. reps_msg->status = CSI_DSP_ERR_ILLEGAL_PARAM;
  916. return XRP_STATUS_SUCCESS;
  917. }
  918. update_task_status(task);
  919. return XRP_STATUS_SUCCESS;
  920. }
  921. static enum xrp_status dsp_task_be_config(void *req,void * resp){
  922. struct csi_dsp_task_be_para *msg= (struct csi_dsp_task_be_para *)req;
  923. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  924. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  925. reps_msg->status = CSI_DSP_OK;
  926. if(!task)
  927. {
  928. reps_msg->status = CSI_DSP_TASK_NOT_VALID;
  929. return XRP_STATUS_SUCCESS;
  930. }
  931. ps_debug("Task be %d to config\n",msg->backend_type);
  932. switch(msg->backend_type)
  933. {
  934. case CSI_DSP_BE_TYPE_HOST:
  935. if(XRP_STATUS_SUCCESS!= ps_sw_task_out_config_message_handler(&msg->sw_param,&task->task_be,task->report_info.buf,task->report_info.buf_size))
  936. {
  937. reps_msg->status = CSI_DSP_BE_CONFIG_FAIL;
  938. return XRP_STATUS_SUCCESS;
  939. }
  940. break;
  941. case CSI_DSP_BE_TYPE_POST_ISP:
  942. if(XRP_STATUS_SUCCESS!= ps_post_isp_config_message_handler(&msg->post_isp_param,&task->task_be))
  943. {
  944. reps_msg->status = CSI_DSP_BE_CONFIG_FAIL;
  945. return XRP_STATUS_SUCCESS;
  946. }
  947. break;
  948. default:
  949. reps_msg->status = CSI_DSP_ERR_ILLEGAL_PARAM;
  950. return XRP_STATUS_SUCCESS;
  951. }
  952. update_task_status(task);
  953. return XRP_STATUS_SUCCESS;
  954. }
  955. static inline int dsp_task_algo_setting_update(csi_dsp_algo_param_t *algo_param ,struct csi_dsp_algo_config_par *new_param)
  956. {
  957. if((new_param->sett_ptr==NULL) ||(new_param->sett_length==0))
  958. {
  959. return 0;
  960. }
  961. if(algo_param->set_buf_ptr ==NULL || algo_param->set_buf_size!=new_param->sett_length)
  962. {
  963. ps_err("update setting invalid dst(0x%x,%d),src(0x%x,%d)\n",\
  964. algo_param->set_buf_ptr,algo_param->set_buf_size,new_param->sett_ptr,new_param->sett_length);
  965. return -1;
  966. }
  967. memcpy(algo_param->set_buf_ptr,(void*)new_param->sett_ptr,algo_param->set_buf_size);
  968. return 0;
  969. }
  970. static inline int dsp_task_algo_buf_update(csi_dsp_algo_param_t *algo_param ,struct csi_dsp_algo_config_par *new_param)
  971. {
  972. int index,loop;
  973. struct csi_dsp_buffer *old_bufs;
  974. struct csi_dsp_buffer *new_bufs;
  975. if((new_param->bufs_ptr==NULL) ||(new_param->buf_num==0))
  976. {
  977. return 0;
  978. }
  979. if(new_param->buf_num>(algo_param->buffer_num-CSI_DSP_HW_TASK_EXTRA_BUF_START_INDEX))
  980. {
  981. return -1;
  982. }
  983. old_bufs = (struct csi_dsp_buffer *)algo_param->buffer_struct_ptr;
  984. new_bufs = (struct csi_dsp_buffer *)new_param->bufs_ptr;
  985. for(loop=0;loop<new_param->buf_num;loop++)
  986. {
  987. index = new_bufs[loop].buf_id;
  988. if(old_bufs[index].buf_id!=index)
  989. {
  990. return -1;
  991. }
  992. memcpy(&old_bufs[index],&new_bufs[loop],sizeof(struct csi_dsp_buffer));
  993. }
  994. ps_debug("exit");
  995. return 0;
  996. }
  997. static enum xrp_status dsp_task_algo_config(void *req,void * resp)
  998. {
  999. struct csi_dsp_algo_config_par *msg= (struct csi_dsp_algo_config_par *)req;
  1000. struct csi_dsp_task_comm_resp *resp_msg= (struct csi_dsp_task_comm_resp *)resp;
  1001. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  1002. resp_msg->status = CSI_DSP_OK;
  1003. struct csi_dsp_buffer *bufs;
  1004. if(!task)
  1005. {
  1006. resp_msg->status = CSI_DSP_TASK_NOT_VALID;
  1007. return XRP_STATUS_SUCCESS;
  1008. }
  1009. if(task->task_algo.param==NULL)
  1010. {
  1011. task->task_algo.param = malloc(sizeof(csi_dsp_algo_param_t));
  1012. if(!task->task_algo.param )
  1013. {
  1014. resp_msg->status = CSI_DSP_MALLO_FAIL;
  1015. return XRP_STATUS_SUCCESS;
  1016. }
  1017. memset(task->task_algo.param,0x0,sizeof(csi_dsp_algo_param_t));
  1018. }
  1019. else
  1020. {
  1021. /*for algo already load, this mean update algo param and buffer*/
  1022. if((task->task_algo.algo_process!=NULL) && (msg->algo_ptr == NULL) && (msg->algo_id == -1))
  1023. {
  1024. if(dsp_task_algo_setting_update(task->task_algo.param,msg))
  1025. {
  1026. ps_err("Algo setting update fail\n");
  1027. resp_msg->status = CSI_DSP_FAIL;
  1028. }
  1029. if(dsp_task_algo_buf_update(task->task_algo.param,msg))
  1030. {
  1031. ps_err("Algo buf update fail\n");
  1032. resp_msg->status = CSI_DSP_FAIL;
  1033. }
  1034. return XRP_STATUS_SUCCESS;
  1035. }
  1036. }
  1037. task->task_algo.algo_process=dsp_algo_load(msg->algo_id,msg->algo_ptr,task->task_algo.param);
  1038. task->task_algo.algo_id=msg->algo_id;
  1039. if(!task->task_algo.algo_process)
  1040. {
  1041. free(task->task_algo.param);
  1042. task->task_algo.param = NULL;
  1043. resp_msg->status = CSI_DSP_ALGO_INVALID;
  1044. ps_err("Algo load fail\n");
  1045. return XRP_STATUS_SUCCESS;
  1046. }
  1047. // /*TODO*/
  1048. // task->task_algo.param->buf_desc_num =2;
  1049. if(task->type&CSI_DSP_TASK_HW)
  1050. {
  1051. if(task->task_algo.param->buf_desc_num)
  1052. {
  1053. task->task_algo.param->buffer_num=task->task_algo.param->buf_desc_num;
  1054. task->task_algo.param->buffer_struct_ptr=malloc(task->task_algo.param->buf_desc_num*sizeof(struct csi_dsp_buffer));
  1055. if(!task->task_algo.param->buffer_struct_ptr)
  1056. {
  1057. free(task->task_algo.param);
  1058. task->task_algo.param = NULL;
  1059. resp_msg->status = CSI_DSP_MALLO_FAIL;
  1060. return XRP_STATUS_SUCCESS;
  1061. }
  1062. memset(task->task_algo.param->buffer_struct_ptr,0x0,task->task_algo.param->buf_desc_num*sizeof(struct csi_dsp_buffer));
  1063. if(msg->sett_ptr!=NULL && msg->sett_length !=0)
  1064. {
  1065. task->task_algo.param->set_buf_size = msg->sett_length;
  1066. task->task_algo.param->set_buf_ptr = malloc(task->task_algo.param->set_buf_size);
  1067. if(!task->task_algo.param->set_buf_ptr)
  1068. {
  1069. free(task->task_algo.param->buffer_struct_ptr);
  1070. free(task->task_algo.param);
  1071. task->task_algo.param = NULL;
  1072. resp_msg->status = CSI_DSP_MALLO_FAIL;
  1073. return XRP_STATUS_SUCCESS;
  1074. }
  1075. memcpy(task->task_algo.param->set_buf_ptr,(void*)msg->sett_ptr,task->task_algo.param->set_buf_size);
  1076. }
  1077. if(msg->bufs_ptr!=NULL && msg->buf_num != 0)
  1078. {
  1079. if((msg->buf_num+CSI_DSP_HW_TASK_EXTRA_BUF_START_INDEX)<=task->task_algo.param->buffer_num)
  1080. {
  1081. bufs = (struct csi_dsp_buffer *)task->task_algo.param->buffer_struct_ptr;
  1082. memcpy(&bufs[CSI_DSP_HW_TASK_EXTRA_BUF_START_INDEX],msg->bufs_ptr,msg->buf_num*(sizeof(struct csi_dsp_buffer)));
  1083. }
  1084. else
  1085. {
  1086. free(task->task_algo.param->buffer_struct_ptr);
  1087. free(task->task_algo.param->set_buf_ptr);
  1088. free(task->task_algo.param);
  1089. task->task_algo.param = NULL;
  1090. resp_msg->status = CSI_DSP_ALGO_BUF_FAIL;
  1091. ps_err("set buf_num:%d,algo buf_num:%d not match fail\n",msg->buf_num,task->task_algo.param->buffer_num);
  1092. return XRP_STATUS_SUCCESS;
  1093. }
  1094. }
  1095. }
  1096. else
  1097. {
  1098. resp_msg->status = CSI_DSP_ALGO_BUF_FAIL;
  1099. ps_err("algo buffer not defined\n");
  1100. return XRP_STATUS_SUCCESS;
  1101. }
  1102. }
  1103. // task->task_algo.param->buffer_num = msg->buf_num;
  1104. // task->task_algo.param->buffer_struct_ptr = msg->bufs_ptr;
  1105. // task->task_algo.param->set_buf_ptr = msg->sett_ptr;
  1106. // task->task_algo.param->set_buf_size = msg->sett_length;
  1107. task->task_algo.param->get_idma_ctrl = dmaif_getDMACtrl;
  1108. task->task_algo.param->printf_func = printf;
  1109. update_task_status(task);
  1110. return XRP_STATUS_SUCCESS;
  1111. }
  1112. static enum xrp_status csi_dsp_task_algo_load(void *in,void * out)
  1113. {
  1114. csi_dsp_algo_load_req_t *req = (csi_dsp_algo_load_req_t *)in;
  1115. csi_dsp_algo_load_resp_t *resp = (csi_dsp_algo_load_resp_t *)out;
  1116. dsp_task_t * task =dsp_search_task_by_id(req->task_id);
  1117. resp->status = CSI_DSP_OK;
  1118. if(!task)
  1119. {
  1120. resp->status = CSI_DSP_TASK_NOT_VALID;
  1121. return XRP_STATUS_SUCCESS;
  1122. }
  1123. task->task_algo.param = malloc(sizeof(csi_dsp_algo_param_t));
  1124. if(!task->task_algo.param )
  1125. {
  1126. resp->status = CSI_DSP_MALLO_FAIL;
  1127. return XRP_STATUS_SUCCESS;
  1128. }
  1129. memset(task->task_algo.param,0x0,sizeof(csi_dsp_algo_param_t));
  1130. task->task_algo.algo_process = dsp_algo_load(req->algo_id,req->algo_ptr,task->task_algo.param);
  1131. if(!task->task_algo.algo_process)
  1132. {
  1133. free(task->task_algo.param);
  1134. resp->status = CSI_DSP_ALGO_LOAD_FAIL;
  1135. return XRP_STATUS_SUCCESS;
  1136. }
  1137. task->task_algo.algo_id = req->algo_id;
  1138. if(task->type&CSI_DSP_TASK_HW )
  1139. {
  1140. if(task->task_algo.param->buf_desc_num)
  1141. {
  1142. task->task_algo.param->buffer_num=task->task_algo.param->buf_desc_num;
  1143. task->task_algo.param->buffer_struct_ptr=malloc(task->task_algo.param->buf_desc_num*sizeof(struct csi_dsp_buffer));
  1144. if(!task->task_algo.param->buffer_struct_ptr)
  1145. {
  1146. free(task->task_algo.param);
  1147. resp->status = CSI_DSP_ALGO_LOAD_FAIL;
  1148. return XRP_STATUS_SUCCESS;
  1149. }
  1150. }
  1151. }
  1152. task->task_algo.param->get_idma_ctrl = dmaif_getDMACtrl;
  1153. task->task_algo.param->printf_func = printf;
  1154. return XRP_STATUS_SUCCESS;
  1155. }
  1156. static enum xrp_status dsp_ip_test_handler(void *req,void * resp)
  1157. {
  1158. struct csi_dsp_ip_test_par *msg = (struct csi_dsp_ip_test_par *)req;
  1159. char argv0[8];
  1160. char argv1[8];
  1161. char argv2[8];
  1162. char *strargv[4];
  1163. strargv[0]=argv0;
  1164. strargv[1]=argv1;
  1165. strargv[2]=argv2;
  1166. strargv[3]=msg->case_goup;
  1167. sprintf(strargv[1], "-v");
  1168. sprintf(strargv[2], "-g");
  1169. run_case(resp,msg->result_buf_size,3, strargv);
  1170. return XRP_STATUS_SUCCESS;
  1171. }
  1172. static enum xrp_status dsp_backend_assgin_buf_handler(void *req,void * resp)
  1173. {
  1174. struct csi_dsp_task_be_para *msg= (struct csi_dsp_task_be_para *)req;
  1175. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  1176. DSP_PROFILE_CUSTOM_START(cmdU)
  1177. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  1178. reps_msg->status = CSI_DSP_OK;
  1179. if(!task)
  1180. {
  1181. reps_msg->status = CSI_DSP_TASK_NOT_VALID;
  1182. return XRP_STATUS_SUCCESS;
  1183. }
  1184. if(XRP_STATUS_SUCCESS != sw_be_asgin_buf(task->task_be.id,&msg->sw_param))
  1185. {
  1186. reps_msg->status = CSI_DSP_BE_ERR;
  1187. }
  1188. DSP_PROFILE_CUSTOM_END(cmdU)
  1189. return XRP_STATUS_SUCCESS;
  1190. }
  1191. enum xrp_status ps_common_command(void *context,
  1192. const void *in_data, size_t in_data_size,
  1193. void *out_data, size_t out_data_size,
  1194. struct xrp_buffer_group *buffer_group)
  1195. {
  1196. (void)out_data_size;
  1197. (void)context;
  1198. size_t sz;
  1199. uint32_t cmd = *(const uint32_t *)in_data;
  1200. void * data =(void *)(in_data+4);
  1201. enum xrp_status status = XRP_STATUS_SUCCESS;
  1202. ps_debug("CMD %d received\n",cmd);
  1203. switch (cmd) {
  1204. case PS_CMD_LOOPBACK_TEST:
  1205. sz = in_data_size> out_data_size?in_data_size:out_data_size;
  1206. memcpy(out_data,in_data+4,sz-4);
  1207. return XRP_STATUS_SUCCESS;
  1208. case PS_CMD_REPORT_CONFIG:
  1209. return ps_register_report_to_task(data);
  1210. case PS_CMD_DATA_MOVE:
  1211. return ps_run_data_move_cmd(data);
  1212. case PS_CMD_TASK_ALLOC:
  1213. return ps_create_task(data,out_data);
  1214. case PS_CMD_TASK_FREE:
  1215. return ps_destroy_task(data,out_data);
  1216. case PS_CMD_TASK_START:
  1217. return dsp_task_start(data,out_data);
  1218. case PS_CMD_TASK_STOP:
  1219. return dsp_task_stop(data,out_data);
  1220. case PS_CMD_FE_CONFIG:
  1221. return dsp_task_fe_config(data,out_data);
  1222. case PS_CMD_BE_CONFIG:
  1223. return dsp_task_be_config(data,out_data);
  1224. case PS_CMD_ALGO_CONFIG:
  1225. return dsp_task_algo_config(data,out_data);
  1226. case PS_CMD_DSP_IP_TEST:
  1227. return dsp_ip_test_handler(data,out_data);
  1228. case PS_CMD_BE_ASSGIN_BUF:
  1229. return dsp_backend_assgin_buf_handler(data,out_data);
  1230. case PS_CMD_ALGO_LOAD:
  1231. return csi_dsp_task_algo_load(data,out_data);
  1232. case PS_CMD_HEART_BEAT_REQ:
  1233. return XRP_STATUS_SUCCESS;
  1234. default:
  1235. return XRP_STATUS_FAILURE;
  1236. }
  1237. }
  1238. int ps_task_shedule(struct xrp_device *device)
  1239. {
  1240. dsp_task_t* task;
  1241. void* report_buf=NULL;
  1242. int size;
  1243. enum task_result status;
  1244. for(;;)
  1245. {
  1246. if(!g_task_rdy_grp)
  1247. {
  1248. continue;
  1249. }
  1250. task=get_ready_task();
  1251. DSP_PROFILE_CUSTOM_ID_ADD(task,task->prio)
  1252. DSP_PROFILE_CUSTOM_START(task);
  1253. if(task->task_pro)
  1254. {
  1255. status=task->task_pro(task);
  1256. if((status&DSP_REPORT_TO_HOST_FLAG))
  1257. {
  1258. // *((int *)task->report_info.buf)=task->report_info.report_id;
  1259. xrp_send_report(device,task->report_info.report_id|DSP_REPORT_TO_HOST_FLAG);
  1260. }
  1261. clr_ready_task(task->prio,task->task_empty_check);
  1262. }
  1263. else
  1264. {
  1265. ps_wrn("ps no valid task handler\n");
  1266. }
  1267. DSP_PROFILE_CUSTOM_END(task);
  1268. }
  1269. ps_wrn("ps schedule exit");
  1270. }
  1271. int ps_task_interrupt_unregister(int32_t pri,uint32_t intrnum)
  1272. {
  1273. int32_t ret = 0;
  1274. // Normally none of these calls should fail. We don't check them
  1275. // individually, any one failing will cause this function to return failure.
  1276. ret = xtos_set_interrupt_handler(intrnum,
  1277. g_scheduler.task_handler[pri]->intr_handler, NULL, NULL);
  1278. g_scheduler.task_handler[pri]->intr_handler=NULL;
  1279. ps_debug("unregister ps interrupt %d\n",intrnum);
  1280. return ret;
  1281. }
  1282. int ps_exception_init()
  1283. {
  1284. enum xrp_status status;
  1285. xrp_user_initialize(&status);
  1286. return status==XRP_STATUS_SUCCESS ?0:-1;
  1287. }