| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/cpu.h>
- #include <linux/freezer.h>
- #include <linux/list.h>
- #include <linux/mutex.h>
- #include <linux/semaphore.h>
- #include <linux/kthread.h>
- #include <linux/delay.h>
- #include "nt_smc_call.h"
- #include "utdriver_macro.h"
- #include "sched_status.h"
- #define CAPI_CALL 0x01
- #define FDRV_CALL 0x02
- #define BDRV_CALL 0x03
- #define SCHED_CALL 0x04
- #define FP_SYS_NO 100
- #define VFS_SYS_NO 0x08
- #define REETIME_SYS_NO 0x07
- #define printk(fmt, args...) printk("\033[;34m[TEEI][TZDriver][switch_fn]"fmt"\033[0m", ##args)
- struct switch_head_struct
- {
- struct list_head head;
- };
- struct switch_call_struct
- {
- int switch_type;
- unsigned long buff_addr;
- };
- static void switch_fn(struct kthread_work *work);
- struct smc_call_struct {
- unsigned long local_cmd;
- u32 teei_cmd_type;
- u32 dev_file_id;
- u32 svc_id;
- u32 cmd_id;
- u32 context;
- u32 enc_id;
- void *cmd_buf;
- size_t cmd_len;
- void *resp_buf;
- size_t resp_len;
- void *meta_data;
- void *info_data;
- size_t info_len;
- int *ret_resp_len;
- int *error_code;
- struct semaphore *psema;
- int retVal;
- };
- extern struct kthread_worker ut_fastcall_worker;
- extern int forward_call_flag;
- extern int fp_call_flag;
- extern int teei_vfs_flag;
- extern int irq_call_flag;
- extern void nt_sched_t_call(void);
- extern int __send_fp_command(unsigned long share_memory_size);
- extern int __vfs_handle(struct service_handler *handler);
- extern int __reetime_handle(struct service_handler *handler);
- extern int __teei_smc_call(unsigned long local_smc_cmd,
- u32 teei_cmd_type,
- u32 dev_file_id,
- u32 svc_id,
- u32 cmd_id,
- u32 context,
- u32 enc_id,
- const void *cmd_buf,
- size_t cmd_len,
- void *resp_buf,
- size_t resp_len,
- const void *meta_data,
- const void *info_data,
- size_t info_len,
- int *ret_resp_len,
- int *error_code,
- struct semaphore *psema);
- static struct switch_call_struct *create_switch_call_struct(void)
- {
- struct switch_call_struct *tmp_entry = NULL;
- tmp_entry = kmalloc(sizeof(struct switch_call_struct), GFP_KERNEL);
- if (tmp_entry == NULL)
- printk("[%s][%d] kmalloc failed!!!\n", __func__, __LINE__);
- return tmp_entry;
- }
- static int init_switch_call_struct(struct switch_call_struct *ent, int work_type, unsigned long buff)
- {
- if ((ent == NULL)) {
- printk("[%s][%d] the paraments are wrong!\n", __func__, __LINE__);
- return -EINVAL;
- }
- ent->switch_type = work_type;
- ent->buff_addr = buff;
- return 0;
- }
- static int destroy_switch_call_struct(struct switch_call_struct *ent)
- {
- kfree(ent);
- return 0;
- }
- struct ut_smc_call_work {
- struct kthread_work work;
- void *data;
- };
- static int ut_smc_call(void *buff)
- {
- struct ut_smc_call_work usc_work = {
- KTHREAD_WORK_INIT(usc_work.work, switch_fn),
- .data = buff,
- };
- if (!queue_kthread_work(&ut_fastcall_worker, &usc_work.work))
- return -1;
- flush_kthread_work(&usc_work.work);
- return 0;
- }
- static int check_work_type(int work_type)
- {
- switch(work_type) {
- case CAPI_CALL:
- case FDRV_CALL:
- case BDRV_CALL:
- case SCHED_CALL:
- return 0;
- default:
- return -EINVAL;
- }
- }
- int add_work_entry(int work_type, unsigned long buff)
- {
- struct switch_call_struct *work_entry = NULL;
- int retVal = 0;
- retVal = check_work_type(work_type);
- if (retVal != 0) {
- printk("[%s][%d] with wrong work_type!\n", __func__, __LINE__);
- return retVal;
- }
- work_entry = create_switch_call_struct();
- if (work_entry == NULL) {
- printk("[%s][%d] There is no enough memory!\n", __func__, __LINE__);
- return -ENOMEM;
- }
- retVal = init_switch_call_struct(work_entry, work_type, buff);
- if (retVal != 0) {
- printk("[%s][%d] init_switch_call_struct failed!\n", __func__, __LINE__);
- destroy_switch_call_struct(work_entry);
- return retVal;
- }
- #if 0
- retVal = add_switch_call_link(&switch_queue_head, work_entry);
- #else
- retVal = ut_smc_call((void *)work_entry);
- #endif
- return retVal;
- }
- #if 0
- int del_work_entry(struct switch_call_struct *ent)
- {
- int retVal = 0;
- retVal = del_switch_call_link(ent);
- if (retVal != 0) {
- printk("[%s][%d] del_switch_call_link failed %d!\n", __func__, __LINE__, retVal);
- return retVal;
- }
- retVal = destroy_switch_call_struct(ent);
- if (retVal != 0) {
- printk("[%s][%d] destroy_switch_call_struct failed %d!\n", __func__, __LINE__, retVal);
- return retVal;
- }
- return 0;
- }
- #endif
- int get_call_type(struct switch_call_struct *ent)
- {
- if (ent == NULL)
- return -EINVAL;
- return ent->switch_type;
- }
- int handle_sched_call(void *buff)
- {
- nt_sched_t();
- return 0;
- }
- int handle_capi_call(void *buff)
- {
- struct smc_call_struct *cd = NULL;
- cd = (struct smc_call_struct *)buff;
- /* with a rmb() */
- rmb();
- cd->retVal = __teei_smc_call(cd->local_cmd,
- cd->teei_cmd_type,
- cd->dev_file_id,
- cd->svc_id,
- cd->cmd_id,
- cd->context,
- cd->enc_id,
- cd->cmd_buf,
- cd->cmd_len,
- cd->resp_buf,
- cd->resp_len,
- cd->meta_data,
- cd->info_data,
- cd->info_len,
- cd->ret_resp_len,
- cd->error_code,
- cd->psema);
- /* with a wmb() */
- wmb();
- return 0;
- }
- struct fdrv_call_struct {
- int fdrv_call_type;
- int fdrv_call_buff_size;
- int retVal;
- };
- int handle_fdrv_call(void *buff)
- {
- struct fdrv_call_struct *cd = NULL;
- cd = (struct fdrv_call_struct *)buff;
- /* with a rmb() */
- rmb();
- switch(cd->fdrv_call_type) {
- case FP_SYS_NO:
- cd->retVal = __send_fp_command(cd->fdrv_call_buff_size);
- break;
- default:
- cd->retVal = -EINVAL;
- }
- /* with a wmb() */
- wmb();
- return 0;
- }
- struct bdrv_call_struct {
- int bdrv_call_type;
- struct service_handler *handler;
- int retVal;
- };
- int handle_bdrv_call(void *buff)
- {
- struct bdrv_call_struct *cd = NULL;
- cd = (struct bdrv_call_struct *)buff;
- /* with a rmb() */
- rmb();
- switch(cd->bdrv_call_type) {
- case VFS_SYS_NO:
- cd->retVal = __vfs_handle(cd->handler);
- kfree(buff);
- break;
- case REETIME_SYS_NO:
- cd->retVal = __reetime_handle(cd->handler);
- kfree(buff);
- break;
- default:
- cd->retVal = -EINVAL;
- }
-
- /* with a wmb() */
- wmb();
- return 0;
- }
- int handle_switch_call(void *buff)
- {
- #if 0
- if (forward_call_flag == GLSCH_FOR_SOTER) {
- forward_call_flag = GLSCH_NONE;
- msleep(10);
- nt_sched_t_call();
- } else if (irq_call_flag == GLSCH_HIGH) {
- printk("[%s][%d]**************************\n", __func__, __LINE__ );
- irq_call_flag = GLSCH_NONE;
- nt_sched_t_call();
- /*msleep_interruptible(10);*/
- } else if (fp_call_flag == GLSCH_HIGH) {
- printk("[%s][%d]**************************\n", __func__, __LINE__ );
- if (teei_vfs_flag == 0) {
- nt_sched_t_call();
- } else {
- msleep_interruptible(1);
- }
- } else if (forward_call_flag == GLSCH_LOW) {
- printk("[%s][%d]**************************\n", __func__, __LINE__ );
- if (teei_vfs_flag == 0) {
- nt_sched_t_call();
- } else {
- msleep_interruptible(1);
- }
- } else {
- printk("[%s][%d]**************************\n", __func__, __LINE__ );
- msleep_interruptible(1);
- }
- #else
- nt_sched_t();
- #endif
- }
- static void switch_fn(struct kthread_work *work)
- {
- struct ut_smc_call_work *switch_work = NULL;
- struct switch_call_struct *switch_ent = NULL;
- int call_type = 0;
- int retVal = 0;
- switch_work = container_of(work, struct ut_smc_call_work, work);
- switch_ent = (struct switch_call_struct *)switch_work->data;
- call_type = get_call_type(switch_ent);
- switch (call_type) {
- case CAPI_CALL:
- retVal = handle_capi_call(switch_ent->buff_addr);
- if (retVal < 0) {
- printk("[%s][%d] fail to handle ClientAPI!\n", __func__, __LINE__);
- }
- break;
- case FDRV_CALL:
- retVal = handle_fdrv_call(switch_ent->buff_addr);
- if (retVal < 0) {
- printk("[%s][%d] fail to handle F-driver!\n", __func__, __LINE__);
- }
- break;
- case BDRV_CALL:
- retVal = handle_bdrv_call(switch_ent->buff_addr);
- if (retVal < 0) {
- printk("[%s][%d] fail to handle B-driver!\n", __func__, __LINE__);
- }
- break;
- case SCHED_CALL:
- retVal = handle_sched_call(switch_ent->buff_addr);
- if (retVal < 0) {
- printk("[%s][%d] fail to handle sched-Call!\n", __func__, __LINE__);
- }
- break;
- default:
- printk("switch fn handles a undefined call! [%d] \n", call_type);
- }
- retVal = destroy_switch_call_struct(switch_ent);
- if (retVal != 0) {
- printk("[%s][%d] destroy_switch_call_struct failed %d!\n", __func__, __LINE__, retVal);
- return retVal;
- }
- return 0;
- }
|