ps_sched.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444
  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 inline csi_dsp_report_e dsp_convert_error_to_report(ehw_error_code err_code)
  585. {
  586. switch(err_code)
  587. {
  588. case EHW_ERROR_VIPRE_NM_OVERFLOW_FLOW:
  589. return CSI_DSP_REPORT_HW_VIPRE_NM_OVERFLOW_FLOW;
  590. case EHW_ERROR_VIPRE_FIFO_OVER_FLOW:
  591. return CSI_DSP_REPORT_HW_VIPRE_FIFO_ERROR;
  592. case EHW_ERROR_VIPRE_BUS_ERROR:
  593. return CSI_DSP_REPORT_HW_VIPRE_BUS_ERROR;
  594. default:
  595. ps_wrn("can't find valid map report id\n");
  596. return CSI_DSP_REPORT_MAX;
  597. }
  598. }
  599. static enum task_result dsp_process_hw_task(void* context)
  600. {
  601. dsp_task_t *task = (dsp_task_t *)context;
  602. entry_struct_t in_info;
  603. struct csi_dsp_buffer out_info;
  604. task->task_algo.param->extra_param_ptr = &extra_param;
  605. task->task_algo.param->extra_param_ptr->report_size = 0;
  606. if(task->task_fe.get_next_entry(task->task_fe.id, &in_info))
  607. {
  608. if(task->task_fe.get_state(task->task_fe.id)==EHW_ERROR_OVER_FLOW)
  609. {
  610. task->task_fe.update_state(task->task_fe.id);
  611. task->task_be.update_state(task->task_be.id);
  612. }
  613. if(task->task_fe.get_state(task->task_fe.id)==EHW_RECOVERYING && task->task_be.get_state(task->task_be.id)==EHW_RECOVERY_DONE)
  614. {
  615. task->task_fe.update_state(task->task_fe.id);
  616. task->task_be.update_state(task->task_be.id);
  617. if(task->report_info.buf)
  618. {
  619. ps_fill_report(task->report_info.buf,CSI_DSP_HW_FRAME_DROP,NULL,0);
  620. }
  621. return PS_TASK_FAILURE_WITH_REPORT;
  622. }
  623. if(task->task_fe.get_state(task->task_fe.id)>=EHW_ERROR_HW_ERR && task->task_fe.get_state(task->task_fe.id)<=EHW_ERROR_HW_ERR_END)
  624. {
  625. if(task->report_info.buf)
  626. {
  627. csi_dsp_report_e report_id = dsp_convert_error_to_report(task->task_fe.get_state(task->task_fe.id));
  628. ps_fill_report(task->report_info.buf,report_id,NULL,0);
  629. }
  630. return PS_TASK_FAILURE_WITH_REPORT;
  631. }
  632. return PS_TASK_FAILURE;
  633. }
  634. #if 0
  635. static uint8_t side=0;
  636. /*********************/
  637. if(in_info.y ==0)
  638. {
  639. side ^=1;
  640. }
  641. if(side == 0 && in_info.y >120)
  642. {
  643. return PS_TASK_SUCCESS;
  644. }
  645. #endif
  646. if(task->task_be.get_next_entry(task->task_be.id,&out_info))
  647. {
  648. if(task->type == CSI_DSP_TASK_HW_TO_SW)
  649. {
  650. /**for back end issue such as no variable buffer drop the coming entry **/
  651. task->task_fe.entry_done(task->task_fe.id,&in_info);
  652. ps_wrn("be get entry fail\n");
  653. }
  654. return PS_TASK_FAILURE;
  655. }
  656. /***************************to pack the algo param******************************/
  657. fill_hw_task_algo_param(task->task_algo.param,&in_info,&out_info);
  658. if(task->task_algo.algo_process == NULL)
  659. {
  660. return PS_TASK_FAILURE;
  661. }
  662. DSP_PROFILE_CUSTOM_START(algo)
  663. if(XRP_STATUS_FAILURE ==task->task_algo.algo_process(task->task_algo.param))
  664. {
  665. // *((csi_dsp_status_e*)out_data) = CSI_DSP_ALGO_ERR;
  666. ps_wrn("Algo run fail\n");
  667. return PS_TASK_FAILURE;
  668. }
  669. DSP_PROFILE_CUSTOM_END(algo)
  670. task->task_fe.entry_done(task->task_fe.id,&in_info);
  671. if(task->task_fe.get_state(task->task_fe.id)!= 0)
  672. {
  673. ps_wrn("Fe Error\n");
  674. return PS_TASK_FAILURE;
  675. }
  676. if(task->task_be.entry_start(task->task_be.id,&out_info))
  677. {
  678. ps_wrn("Be trigger fail\n");
  679. if(task->task_be.get_state(task->task_be.id) < 0)
  680. {
  681. if(task->type == CSI_DSP_TASK_HW_TO_SW)
  682. return PS_TASK_FAILURE_WITH_REPORT;
  683. if(task->task_be.get_state(task->task_be.id)==EHW_ERROR_OVER_FLOW)
  684. {
  685. task->task_fe.update_state(task->task_fe.id);
  686. task->task_be.update_state(task->task_be.id);
  687. }
  688. }
  689. return PS_TASK_FAILURE;
  690. }
  691. if(task->type == CSI_DSP_TASK_HW_TO_SW)
  692. {
  693. csi_dsp_result_report(task->report_info.buf,(void*)&out_info,sizeof(out_info),(void*)extra_param.report_buf,extra_param.report_size);
  694. return PS_TASK_SUCCESS_WITH_REPORT;
  695. }
  696. return PS_TASK_SUCCESS;
  697. }
  698. static enum xrp_status ps_create_task(void *req,void * resp)
  699. {
  700. struct csi_dsp_task_create_req *msg= (struct csi_dsp_task_create_req *)req;
  701. struct csi_dsp_task_create_resp *reps_msg= (struct csi_dsp_task_create_resp *)resp;
  702. dsp_task_t* new_task;
  703. int task_id =-1;
  704. enum xrp_status status;
  705. ps_debug("Task type %d to create\n",msg->type);
  706. switch(msg->type)
  707. {
  708. case CSI_DSP_TASK_SW:
  709. case CSI_DSP_TASK_SW_TO_SW:
  710. case CSI_DSP_TASK_SW_TO_HW:
  711. new_task = get_free_sw_task();
  712. if(!new_task)
  713. {
  714. reps_msg->status = CSI_DSP_TASK_ALLOC_FAIL;
  715. return XRP_STATUS_SUCCESS;
  716. }
  717. allocte_ns_id(new_task->prio,new_task->nsid);
  718. xrp_device_register_namespace(g_scheduler.device,new_task->nsid,dsp_process_sw_task, new_task, &status);
  719. if(status!=XRP_STATUS_SUCCESS)
  720. {
  721. reps_msg->status = CSI_DSP_TASK_ALLOC_FAIL;
  722. return XRP_STATUS_SUCCESS;
  723. }
  724. break;
  725. case CSI_DSP_TASK_HW:
  726. case CSI_DSP_TASK_HW_TO_SW:
  727. case CSI_DSP_TASK_HW_TO_HW:
  728. new_task = get_free_hw_task();
  729. if(!new_task)
  730. {
  731. reps_msg->status = CSI_DSP_TASK_ALLOC_FAIL;
  732. return XRP_STATUS_SUCCESS;
  733. }
  734. allocte_ns_id(new_task->prio,new_task->nsid);
  735. new_task->task_pro = dsp_process_hw_task;
  736. break;
  737. default:
  738. reps_msg->status =CSI_DSP_ERR_ILLEGAL_PARAM;
  739. return XRP_STATUS_SUCCESS;
  740. }
  741. if(msg->type == CSI_DSP_TASK_SW_TO_SW)
  742. {
  743. new_task->status = DSP_TASK_STATUS_READY;
  744. }
  745. else
  746. {
  747. new_task->status = DSP_TASK_STATUS_IDEL;
  748. }
  749. new_task->type = msg->type;
  750. new_task->report_info.buf=NULL;
  751. new_task->report_info.buf_size=0;
  752. new_task->report_info.report_id=-1;
  753. new_task->task_fe.type= CSI_DSP_FE_TYPE_INVALID;
  754. new_task->task_be.type= CSI_DSP_BE_TYPE_INVALID;
  755. new_task->task_algo.algo_id=-1;
  756. new_task->task_algo.param = NULL;
  757. // g_scheduler.task_handler[task_id]=new_task;
  758. task_id = dsp_add_task_to_scheduler(new_task);
  759. if(task_id <0)
  760. {
  761. reps_msg->status = CSI_DSP_TASK_ADD_TO_SCHEDULER_FAIL;
  762. release_task(new_task);
  763. return XRP_STATUS_SUCCESS;
  764. }
  765. reps_msg->status = CSI_DSP_OK;
  766. reps_msg->task_id = task_id;
  767. // g_scheduler.task_num++;
  768. memcpy(reps_msg->task_ns,new_task->nsid,XRP_NAMESPACE_ID_SIZE);
  769. return XRP_STATUS_SUCCESS;
  770. }
  771. static enum xrp_status ps_destroy_task(void *req,void * resp)
  772. {
  773. struct csi_dsp_task_free_req *msg = (struct csi_dsp_task_free_req*)req;
  774. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  775. reps_msg->status = CSI_DSP_OK;
  776. enum xrp_status status;
  777. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  778. if(!task)
  779. {
  780. reps_msg->status = CSI_DSP_TASK_NOT_VALID;
  781. return XRP_STATUS_SUCCESS;
  782. }
  783. dsp_remove_task_from_scheduler(msg->task_id);
  784. if(task->task_algo.param)
  785. {
  786. if(CSI_DSP_TASK_HW & task->type)
  787. {
  788. if(task->task_algo.param->buffer_struct_ptr)
  789. free(task->task_algo.param->buffer_struct_ptr);
  790. if(task->task_algo.param->set_buf_ptr)
  791. free(task->task_algo.param->set_buf_ptr);
  792. }
  793. free(task->task_algo.param);
  794. }
  795. task->task_algo.param = NULL;
  796. task->task_algo.algo_id =-1;
  797. task->task_algo.algo_process = NULL;
  798. if(CSI_DSP_TASK_SW & task->type)
  799. {
  800. xrp_device_unregister_namespace(g_scheduler.device,task->nsid,&status);
  801. }
  802. release_task(task);
  803. reps_msg->status = CSI_DSP_OK;
  804. return XRP_STATUS_SUCCESS;
  805. }
  806. static enum xrp_status dsp_task_start(void *req,void * resp){
  807. struct csi_dsp_task_start_req *msg= (struct csi_dsp_task_start_req *)req;
  808. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  809. ps_debug("task %d to start\n",msg->task_id);
  810. dsp_task_t *task = dsp_search_task_by_id(msg->task_id);
  811. if(task == NULL)
  812. {
  813. reps_msg->status = CSI_DSP_ERR_ILLEGAL_PARAM;
  814. return XRP_STATUS_SUCCESS;
  815. }
  816. if(task->status == DSP_TASK_STATUS_RUNING)
  817. {
  818. reps_msg->status = CSI_DSP_TASK_ALREADY_RUNNING;
  819. return XRP_STATUS_SUCCESS;
  820. }
  821. else if(task->status ==DSP_TASK_STATUS_READY)
  822. {
  823. /*TODO enable task.. enable the HW INIT */
  824. if(0!=ps_task_interrupt_register(task->prio,task->irq_num))
  825. {
  826. return XRP_STATUS_FAILURE;
  827. }
  828. task->status = DSP_TASK_STATUS_RUNING;
  829. reps_msg->status = CSI_DSP_OK;
  830. return XRP_STATUS_SUCCESS;
  831. }
  832. else
  833. {
  834. reps_msg->status = CSI_DSP_TASK_START_FAIL;
  835. return XRP_STATUS_SUCCESS;
  836. }
  837. }
  838. static enum xrp_status dsp_task_stop(void *req,void * resp){
  839. struct csi_dsp_task_start_req *msg= (struct csi_dsp_task_start_req *)req;
  840. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  841. ps_debug("task %d to stop\n",msg->task_id);
  842. dsp_task_t *task = dsp_search_task_by_id(msg->task_id);
  843. reps_msg->status = CSI_DSP_OK;
  844. if(task == NULL)
  845. {
  846. reps_msg->status = CSI_DSP_ERR_ILLEGAL_PARAM;
  847. return XRP_STATUS_SUCCESS;
  848. }
  849. if(task->status == DSP_TASK_STATUS_RUNING)
  850. {
  851. ps_task_interrupt_disable(task->prio,task->irq_num);
  852. task->status = DSP_TASK_STATUS_READY;
  853. return XRP_STATUS_SUCCESS;
  854. }
  855. else
  856. {
  857. return XRP_STATUS_SUCCESS;
  858. }
  859. }
  860. static inline void update_task_status(dsp_task_t * task )
  861. {
  862. switch(task->type)
  863. {
  864. case CSI_DSP_TASK_SW_TO_HW:
  865. if((task->status == DSP_TASK_STATUS_IDEL) &&
  866. (task->task_be.type!=CSI_DSP_BE_TYPE_INVALID) &&
  867. (task->task_algo.algo_process!=NULL))
  868. {
  869. task->status= DSP_TASK_STATUS_READY;
  870. }
  871. break;
  872. case CSI_DSP_TASK_HW_TO_SW:
  873. if((task->status == DSP_TASK_STATUS_IDEL) &&
  874. (task->task_fe.type!=CSI_DSP_FE_TYPE_INVALID) &&
  875. (task->task_be.type!=CSI_DSP_BE_TYPE_INVALID)&&
  876. (task->task_algo.algo_process!=NULL))
  877. {
  878. task->status= DSP_TASK_STATUS_READY;
  879. }
  880. break;
  881. case CSI_DSP_TASK_HW_TO_HW:
  882. if((task->status == DSP_TASK_STATUS_IDEL) &&
  883. (task->task_fe.type!=CSI_DSP_FE_TYPE_INVALID) &&
  884. (task->task_be.type!=CSI_DSP_BE_TYPE_INVALID)&&
  885. (task->task_algo.algo_process!=NULL))
  886. {
  887. task->status= DSP_TASK_STATUS_READY;
  888. }
  889. break;
  890. default:
  891. break;
  892. }
  893. }
  894. int high_pri_task =-1;
  895. static bool dsp_vipre_task_check()
  896. {
  897. if( ps_is_vipre_task_empty()== true || high_pri_task<0 )
  898. {
  899. return true;
  900. }
  901. set_ready_task(high_pri_task);
  902. return false;
  903. }
  904. static enum xrp_status dsp_task_fe_config(void *req,void * resp){
  905. struct csi_dsp_task_fe_para *msg= (struct csi_dsp_task_fe_para *)req;
  906. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  907. reps_msg->status = CSI_DSP_OK;
  908. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  909. if(!task)
  910. {
  911. reps_msg->status = CSI_DSP_TASK_NOT_VALID;
  912. return XRP_STATUS_SUCCESS;
  913. }
  914. ps_debug("FE %d to config\n",msg->frontend_type);
  915. switch(msg->frontend_type)
  916. {
  917. case CSI_DSP_FE_TYPE_CPU:
  918. break;
  919. case CSI_DSP_FE_TYPE_ISP:
  920. if(XRP_STATUS_SUCCESS!=ps_isp_config_message_handler((void*)&msg->isp_param,(void*)&task->task_fe))
  921. {
  922. reps_msg->status = CSI_DSP_FE_CONFIG_FAIL;
  923. return XRP_STATUS_SUCCESS;
  924. }
  925. task->irq_num = ps_get_isp_irq(msg->isp_param.id);
  926. break;
  927. case CSI_DSP_FE_TYPE_VIPRE:
  928. if(XRP_STATUS_SUCCESS!=ps_vipre_config_message_handler((void*)&msg->isp_param,(void*)&task->task_fe))
  929. {
  930. reps_msg->status = CSI_DSP_FE_CONFIG_FAIL;
  931. return XRP_STATUS_SUCCESS;
  932. }
  933. task->irq_num = ps_get_vipre_irq();
  934. high_pri_task = dsp_search_higher_prio_task(task);
  935. if(high_pri_task >=0)
  936. {
  937. task->task_empty_check = dsp_vipre_task_check;
  938. }
  939. else
  940. {
  941. task->task_empty_check = NULL;
  942. }
  943. break;
  944. default:
  945. reps_msg->status = CSI_DSP_ERR_ILLEGAL_PARAM;
  946. return XRP_STATUS_SUCCESS;
  947. }
  948. update_task_status(task);
  949. return XRP_STATUS_SUCCESS;
  950. }
  951. static enum xrp_status dsp_task_be_config(void *req,void * resp){
  952. struct csi_dsp_task_be_para *msg= (struct csi_dsp_task_be_para *)req;
  953. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  954. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  955. reps_msg->status = CSI_DSP_OK;
  956. if(!task)
  957. {
  958. reps_msg->status = CSI_DSP_TASK_NOT_VALID;
  959. return XRP_STATUS_SUCCESS;
  960. }
  961. ps_debug("Task be %d to config\n",msg->backend_type);
  962. switch(msg->backend_type)
  963. {
  964. case CSI_DSP_BE_TYPE_HOST:
  965. 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))
  966. {
  967. reps_msg->status = CSI_DSP_BE_CONFIG_FAIL;
  968. return XRP_STATUS_SUCCESS;
  969. }
  970. break;
  971. case CSI_DSP_BE_TYPE_POST_ISP:
  972. if(XRP_STATUS_SUCCESS!= ps_post_isp_config_message_handler(&msg->post_isp_param,&task->task_be))
  973. {
  974. reps_msg->status = CSI_DSP_BE_CONFIG_FAIL;
  975. return XRP_STATUS_SUCCESS;
  976. }
  977. break;
  978. default:
  979. reps_msg->status = CSI_DSP_ERR_ILLEGAL_PARAM;
  980. return XRP_STATUS_SUCCESS;
  981. }
  982. update_task_status(task);
  983. return XRP_STATUS_SUCCESS;
  984. }
  985. static inline int dsp_task_algo_setting_update(csi_dsp_algo_param_t *algo_param ,struct csi_dsp_algo_config_par *new_param)
  986. {
  987. if((new_param->sett_ptr==NULL) ||(new_param->sett_length==0))
  988. {
  989. return 0;
  990. }
  991. if(algo_param->set_buf_ptr ==NULL || algo_param->set_buf_size!=new_param->sett_length)
  992. {
  993. ps_err("update setting invalid dst(0x%x,%d),src(0x%x,%d)\n",\
  994. algo_param->set_buf_ptr,algo_param->set_buf_size,new_param->sett_ptr,new_param->sett_length);
  995. return -1;
  996. }
  997. memcpy(algo_param->set_buf_ptr,(void*)new_param->sett_ptr,algo_param->set_buf_size);
  998. return 0;
  999. }
  1000. static inline int dsp_task_algo_buf_update(csi_dsp_algo_param_t *algo_param ,struct csi_dsp_algo_config_par *new_param)
  1001. {
  1002. int index,loop;
  1003. struct csi_dsp_buffer *old_bufs;
  1004. struct csi_dsp_buffer *new_bufs;
  1005. if((new_param->bufs_ptr==NULL) ||(new_param->buf_num==0))
  1006. {
  1007. return 0;
  1008. }
  1009. if(new_param->buf_num>(algo_param->buffer_num-CSI_DSP_HW_TASK_EXTRA_BUF_START_INDEX))
  1010. {
  1011. return -1;
  1012. }
  1013. old_bufs = (struct csi_dsp_buffer *)algo_param->buffer_struct_ptr;
  1014. new_bufs = (struct csi_dsp_buffer *)new_param->bufs_ptr;
  1015. for(loop=0;loop<new_param->buf_num;loop++)
  1016. {
  1017. index = new_bufs[loop].buf_id;
  1018. if(old_bufs[index].buf_id!=index)
  1019. {
  1020. return -1;
  1021. }
  1022. memcpy(&old_bufs[index],&new_bufs[loop],sizeof(struct csi_dsp_buffer));
  1023. }
  1024. ps_debug("exit");
  1025. return 0;
  1026. }
  1027. static enum xrp_status dsp_task_algo_config(void *req,void * resp)
  1028. {
  1029. struct csi_dsp_algo_config_par *msg= (struct csi_dsp_algo_config_par *)req;
  1030. struct csi_dsp_task_comm_resp *resp_msg= (struct csi_dsp_task_comm_resp *)resp;
  1031. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  1032. resp_msg->status = CSI_DSP_OK;
  1033. struct csi_dsp_buffer *bufs;
  1034. if(!task)
  1035. {
  1036. resp_msg->status = CSI_DSP_TASK_NOT_VALID;
  1037. return XRP_STATUS_SUCCESS;
  1038. }
  1039. if(task->task_algo.param==NULL)
  1040. {
  1041. task->task_algo.param = malloc(sizeof(csi_dsp_algo_param_t));
  1042. if(!task->task_algo.param )
  1043. {
  1044. resp_msg->status = CSI_DSP_MALLO_FAIL;
  1045. return XRP_STATUS_SUCCESS;
  1046. }
  1047. memset(task->task_algo.param,0x0,sizeof(csi_dsp_algo_param_t));
  1048. }
  1049. else
  1050. {
  1051. /*for algo already load, this mean update algo param and buffer*/
  1052. if((task->task_algo.algo_process!=NULL) && (msg->algo_ptr == NULL) && (msg->algo_id == -1))
  1053. {
  1054. if(dsp_task_algo_setting_update(task->task_algo.param,msg))
  1055. {
  1056. ps_err("Algo setting update fail\n");
  1057. resp_msg->status = CSI_DSP_FAIL;
  1058. }
  1059. if(dsp_task_algo_buf_update(task->task_algo.param,msg))
  1060. {
  1061. ps_err("Algo buf update fail\n");
  1062. resp_msg->status = CSI_DSP_FAIL;
  1063. }
  1064. return XRP_STATUS_SUCCESS;
  1065. }
  1066. }
  1067. task->task_algo.algo_process=dsp_algo_load(msg->algo_id,msg->algo_ptr,task->task_algo.param);
  1068. task->task_algo.algo_id=msg->algo_id;
  1069. if(!task->task_algo.algo_process)
  1070. {
  1071. free(task->task_algo.param);
  1072. task->task_algo.param = NULL;
  1073. resp_msg->status = CSI_DSP_ALGO_INVALID;
  1074. ps_err("Algo load fail\n");
  1075. return XRP_STATUS_SUCCESS;
  1076. }
  1077. // /*TODO*/
  1078. // task->task_algo.param->buf_desc_num =2;
  1079. if(task->type&CSI_DSP_TASK_HW)
  1080. {
  1081. if(task->task_algo.param->buf_desc_num)
  1082. {
  1083. task->task_algo.param->buffer_num=task->task_algo.param->buf_desc_num;
  1084. task->task_algo.param->buffer_struct_ptr=malloc(task->task_algo.param->buf_desc_num*sizeof(struct csi_dsp_buffer));
  1085. if(!task->task_algo.param->buffer_struct_ptr)
  1086. {
  1087. free(task->task_algo.param);
  1088. task->task_algo.param = NULL;
  1089. resp_msg->status = CSI_DSP_MALLO_FAIL;
  1090. return XRP_STATUS_SUCCESS;
  1091. }
  1092. memset(task->task_algo.param->buffer_struct_ptr,0x0,task->task_algo.param->buf_desc_num*sizeof(struct csi_dsp_buffer));
  1093. if(msg->sett_ptr!=NULL && msg->sett_length !=0)
  1094. {
  1095. task->task_algo.param->set_buf_size = msg->sett_length;
  1096. task->task_algo.param->set_buf_ptr = malloc(task->task_algo.param->set_buf_size);
  1097. if(!task->task_algo.param->set_buf_ptr)
  1098. {
  1099. free(task->task_algo.param->buffer_struct_ptr);
  1100. free(task->task_algo.param);
  1101. task->task_algo.param = NULL;
  1102. resp_msg->status = CSI_DSP_MALLO_FAIL;
  1103. return XRP_STATUS_SUCCESS;
  1104. }
  1105. memcpy(task->task_algo.param->set_buf_ptr,(void*)msg->sett_ptr,task->task_algo.param->set_buf_size);
  1106. }
  1107. if(msg->bufs_ptr!=NULL && msg->buf_num != 0)
  1108. {
  1109. if((msg->buf_num+CSI_DSP_HW_TASK_EXTRA_BUF_START_INDEX)<=task->task_algo.param->buffer_num)
  1110. {
  1111. bufs = (struct csi_dsp_buffer *)task->task_algo.param->buffer_struct_ptr;
  1112. memcpy(&bufs[CSI_DSP_HW_TASK_EXTRA_BUF_START_INDEX],msg->bufs_ptr,msg->buf_num*(sizeof(struct csi_dsp_buffer)));
  1113. }
  1114. else
  1115. {
  1116. free(task->task_algo.param->buffer_struct_ptr);
  1117. free(task->task_algo.param->set_buf_ptr);
  1118. free(task->task_algo.param);
  1119. task->task_algo.param = NULL;
  1120. resp_msg->status = CSI_DSP_ALGO_BUF_FAIL;
  1121. ps_err("set buf_num:%d,algo buf_num:%d not match fail\n",msg->buf_num,task->task_algo.param->buffer_num);
  1122. return XRP_STATUS_SUCCESS;
  1123. }
  1124. }
  1125. }
  1126. else
  1127. {
  1128. resp_msg->status = CSI_DSP_ALGO_BUF_FAIL;
  1129. ps_err("algo buffer not defined\n");
  1130. return XRP_STATUS_SUCCESS;
  1131. }
  1132. }
  1133. // task->task_algo.param->buffer_num = msg->buf_num;
  1134. // task->task_algo.param->buffer_struct_ptr = msg->bufs_ptr;
  1135. // task->task_algo.param->set_buf_ptr = msg->sett_ptr;
  1136. // task->task_algo.param->set_buf_size = msg->sett_length;
  1137. task->task_algo.param->get_idma_ctrl = dmaif_getDMACtrl;
  1138. task->task_algo.param->printf_func = printf;
  1139. update_task_status(task);
  1140. return XRP_STATUS_SUCCESS;
  1141. }
  1142. static enum xrp_status csi_dsp_task_algo_load(void *in,void * out)
  1143. {
  1144. csi_dsp_algo_load_req_t *req = (csi_dsp_algo_load_req_t *)in;
  1145. csi_dsp_algo_load_resp_t *resp = (csi_dsp_algo_load_resp_t *)out;
  1146. dsp_task_t * task =dsp_search_task_by_id(req->task_id);
  1147. resp->status = CSI_DSP_OK;
  1148. if(!task)
  1149. {
  1150. resp->status = CSI_DSP_TASK_NOT_VALID;
  1151. return XRP_STATUS_SUCCESS;
  1152. }
  1153. task->task_algo.param = malloc(sizeof(csi_dsp_algo_param_t));
  1154. if(!task->task_algo.param )
  1155. {
  1156. resp->status = CSI_DSP_MALLO_FAIL;
  1157. return XRP_STATUS_SUCCESS;
  1158. }
  1159. memset(task->task_algo.param,0x0,sizeof(csi_dsp_algo_param_t));
  1160. task->task_algo.algo_process = dsp_algo_load(req->algo_id,req->algo_ptr,task->task_algo.param);
  1161. if(!task->task_algo.algo_process)
  1162. {
  1163. free(task->task_algo.param);
  1164. resp->status = CSI_DSP_ALGO_LOAD_FAIL;
  1165. return XRP_STATUS_SUCCESS;
  1166. }
  1167. task->task_algo.algo_id = req->algo_id;
  1168. if(task->type&CSI_DSP_TASK_HW )
  1169. {
  1170. if(task->task_algo.param->buf_desc_num)
  1171. {
  1172. task->task_algo.param->buffer_num=task->task_algo.param->buf_desc_num;
  1173. task->task_algo.param->buffer_struct_ptr=malloc(task->task_algo.param->buf_desc_num*sizeof(struct csi_dsp_buffer));
  1174. if(!task->task_algo.param->buffer_struct_ptr)
  1175. {
  1176. free(task->task_algo.param);
  1177. resp->status = CSI_DSP_ALGO_LOAD_FAIL;
  1178. return XRP_STATUS_SUCCESS;
  1179. }
  1180. }
  1181. }
  1182. task->task_algo.param->get_idma_ctrl = dmaif_getDMACtrl;
  1183. task->task_algo.param->printf_func = printf;
  1184. return XRP_STATUS_SUCCESS;
  1185. }
  1186. static enum xrp_status dsp_ip_test_handler(void *req,void * resp)
  1187. {
  1188. struct csi_dsp_ip_test_par *msg = (struct csi_dsp_ip_test_par *)req;
  1189. char argv0[8];
  1190. char argv1[8];
  1191. char argv2[8];
  1192. char *strargv[4];
  1193. strargv[0]=argv0;
  1194. strargv[1]=argv1;
  1195. strargv[2]=argv2;
  1196. strargv[3]=msg->case_goup;
  1197. sprintf(strargv[1], "-v");
  1198. sprintf(strargv[2], "-g");
  1199. run_case(resp,msg->result_buf_size,3, strargv);
  1200. return XRP_STATUS_SUCCESS;
  1201. }
  1202. static enum xrp_status dsp_backend_assgin_buf_handler(void *req,void * resp)
  1203. {
  1204. struct csi_dsp_task_be_para *msg= (struct csi_dsp_task_be_para *)req;
  1205. struct csi_dsp_task_comm_resp *reps_msg= (struct csi_dsp_task_comm_resp *)resp;
  1206. DSP_PROFILE_CUSTOM_START(cmdU)
  1207. dsp_task_t * task =dsp_search_task_by_id(msg->task_id);
  1208. reps_msg->status = CSI_DSP_OK;
  1209. if(!task)
  1210. {
  1211. reps_msg->status = CSI_DSP_TASK_NOT_VALID;
  1212. return XRP_STATUS_SUCCESS;
  1213. }
  1214. if(XRP_STATUS_SUCCESS != sw_be_asgin_buf(task->task_be.id,&msg->sw_param))
  1215. {
  1216. reps_msg->status = CSI_DSP_BE_ERR;
  1217. }
  1218. DSP_PROFILE_CUSTOM_END(cmdU)
  1219. return XRP_STATUS_SUCCESS;
  1220. }
  1221. enum xrp_status ps_common_command(void *context,
  1222. const void *in_data, size_t in_data_size,
  1223. void *out_data, size_t out_data_size,
  1224. struct xrp_buffer_group *buffer_group)
  1225. {
  1226. (void)out_data_size;
  1227. (void)context;
  1228. size_t sz;
  1229. uint32_t cmd = *(const uint32_t *)in_data;
  1230. void * data =(void *)(in_data+4);
  1231. enum xrp_status status = XRP_STATUS_SUCCESS;
  1232. ps_debug("CMD %d received\n",cmd);
  1233. switch (cmd) {
  1234. case PS_CMD_LOOPBACK_TEST:
  1235. sz = in_data_size> out_data_size?in_data_size:out_data_size;
  1236. memcpy(out_data,in_data+4,sz-4);
  1237. return XRP_STATUS_SUCCESS;
  1238. case PS_CMD_REPORT_CONFIG:
  1239. return ps_register_report_to_task(data);
  1240. case PS_CMD_DATA_MOVE:
  1241. return ps_run_data_move_cmd(data);
  1242. case PS_CMD_TASK_ALLOC:
  1243. return ps_create_task(data,out_data);
  1244. case PS_CMD_TASK_FREE:
  1245. return ps_destroy_task(data,out_data);
  1246. case PS_CMD_TASK_START:
  1247. return dsp_task_start(data,out_data);
  1248. case PS_CMD_TASK_STOP:
  1249. return dsp_task_stop(data,out_data);
  1250. case PS_CMD_FE_CONFIG:
  1251. return dsp_task_fe_config(data,out_data);
  1252. case PS_CMD_BE_CONFIG:
  1253. return dsp_task_be_config(data,out_data);
  1254. case PS_CMD_ALGO_CONFIG:
  1255. return dsp_task_algo_config(data,out_data);
  1256. case PS_CMD_DSP_IP_TEST:
  1257. return dsp_ip_test_handler(data,out_data);
  1258. case PS_CMD_BE_ASSGIN_BUF:
  1259. return dsp_backend_assgin_buf_handler(data,out_data);
  1260. case PS_CMD_ALGO_LOAD:
  1261. return csi_dsp_task_algo_load(data,out_data);
  1262. case PS_CMD_HEART_BEAT_REQ:
  1263. return XRP_STATUS_SUCCESS;
  1264. default:
  1265. return XRP_STATUS_FAILURE;
  1266. }
  1267. }
  1268. int ps_task_shedule(struct xrp_device *device)
  1269. {
  1270. dsp_task_t* task;
  1271. void* report_buf=NULL;
  1272. int size;
  1273. enum task_result status;
  1274. for(;;)
  1275. {
  1276. if(!g_task_rdy_grp)
  1277. {
  1278. continue;
  1279. }
  1280. task=get_ready_task();
  1281. DSP_PROFILE_CUSTOM_ID_ADD(task,task->prio)
  1282. DSP_PROFILE_CUSTOM_START(task);
  1283. if(task->task_pro)
  1284. {
  1285. status=task->task_pro(task);
  1286. if((status&DSP_REPORT_TO_HOST_FLAG))
  1287. {
  1288. // *((int *)task->report_info.buf)=task->report_info.report_id;
  1289. xrp_send_report(device,task->report_info.report_id|DSP_REPORT_TO_HOST_FLAG);
  1290. }
  1291. clr_ready_task(task->prio,task->task_empty_check);
  1292. }
  1293. else
  1294. {
  1295. ps_wrn("ps no valid task handler\n");
  1296. }
  1297. DSP_PROFILE_CUSTOM_END(task);
  1298. }
  1299. ps_wrn("ps schedule exit");
  1300. }
  1301. int ps_task_interrupt_unregister(int32_t pri,uint32_t intrnum)
  1302. {
  1303. int32_t ret = 0;
  1304. // Normally none of these calls should fail. We don't check them
  1305. // individually, any one failing will cause this function to return failure.
  1306. ret = xtos_set_interrupt_handler(intrnum,
  1307. g_scheduler.task_handler[pri]->intr_handler, NULL, NULL);
  1308. g_scheduler.task_handler[pri]->intr_handler=NULL;
  1309. ps_debug("unregister ps interrupt %d\n",intrnum);
  1310. return ret;
  1311. }
  1312. int ps_exception_init()
  1313. {
  1314. enum xrp_status status;
  1315. xrp_user_initialize(&status);
  1316. return status==XRP_STATUS_SUCCESS ?0:-1;
  1317. }