| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054 |
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/platform_device.h>
- #include <linux/debugfs.h>
- #include <linux/cdev.h>
- #include <linux/uaccess.h>
- #include <linux/sched.h>
- #include <linux/list.h>
- #include <linux/mutex.h>
- #include <linux/io.h>
- #include <linux/interrupt.h>
- #include <linux/wait.h>
- #include <asm/cacheflush.h>
- #include <linux/delay.h>
- #include <linux/irq.h>
- #include <asm/uaccess.h>
- #include <mach/mt_clkmgr.h>
- #include <linux/of.h>
- #include <linux/of_irq.h>
- /*#include <mach/eint.h>*/
- /*#include <mach/eint_drv.h>*/
- #include <linux/irqchip/mt-eic.h>
- #include <linux/compat.h>
- #include <linux/freezer.h>
- #include <linux/cpumask.h>
- #include "tpd.h"
- #include <linux/delay.h>
- #include <linux/cpu.h>
- #include "teei_client.h"
- #include "teei_common.h"
- #include "teei_id.h"
- #include "teei_debug.h"
- #include "smc_id.h"
- /* #include "TEEI.h" */
- #include "tz_service.h"
- #include "nt_smc_call.h"
- #include "teei_client_main.h"
- #include "utos_version.h"
- #include <linux/of.h>
- #include <linux/of_address.h>
- #include <linux/completion.h>
- #include <linux/kthread.h>
- #include <linux/module.h>
- #include <linux/device.h>
- #include <linux/workqueue.h>
- #include <linux/cpu.h>
- #include <linux/moduleparam.h>
- #define MAX_BUFF_SIZE (4096)
- #define NQ_SIZE (4096)
- #define CTL_BUFF_SIZE (4096)
- #define VDRV_MAX_SIZE (0x80000)
- #define NQ_VALID 1
- #define TEEI_VFS_NUM 0x8
- #define F_CREATE_NQ_ID 0x01
- #define F_CREATE_CTL_ID 0x02
- #define F_CREATE_VDRV_ID 0x04
- #define MESSAGE_SIZE (4096)
- #define VALID_TYPE (1)
- #define INVALID_TYPE (0)
- #define FAST_CALL_TYPE (0x100)
- #define STANDARD_CALL_TYPE (0x200)
- #define TYPE_NONE (0x300)
- #define FAST_CREAT_NQ (0x40)
- #define FAST_ACK_CREAT_NQ (0x41)
- #define FAST_CREAT_VDRV (0x42)
- #define FAST_ACK_CREAT_VDRV (0x43)
- #define FAST_CREAT_SYS_CTL (0x44)
- #define FAST_ACK_CREAT_SYS_CTL (0x45)
- #define NQ_CALL_TYPE (0x60)
- #define VDRV_CALL_TYPE (0x61)
- #define SCHD_CALL_TYPE (0x62)
- #define FDRV_ACK_TYPE (0x63)
- #define STD_INIT_CONTEXT (0x80)
- #define STD_ACK_INIT_CONTEXT (0x81)
- #define STD_OPEN_SESSION (0x82)
- #define STD_ACK_OPEN_SESSION (0x83)
- #define STD_INVOKE_CMD (0x84)
- #define STD_ACK_INVOKE_CMD (0x85)
- #define STD_CLOSE_SESSION (0x86)
- #define STD_ACK_CLOSE_SESSION (0x87)
- #define STD_CLOSE_CONTEXT (0x88)
- #define STD_ACK_CLOSE_CONTEXT (0x89)
- #define GLSCH_NEG (0x03)
- #define GLSCH_NONE (0x00)
- #define GLSCH_LOW (0x01)
- #define GLSCH_HIGH (0x02)
- #define GLSCH_FOR_SOTER (0x04)
- #define BOOT_IRQ (283)
- #define SCHED_IRQ (284)
- #define SOTER_IRQ (285)
- #define FP_ACK_IRQ (287)
- #define BDRV_IRQ (278)
- #define TEEI_LOG_IRQ (277)
- #define SOTER_ERROR_IRQ (276)
- #define TLOG_CONTEXT_LEN (300)
- #define TLOG_MAX_CNT (50)
- #define TLOG_UNUSE (0)
- #define TLOG_INUSE (1)
- #if 0
- /******************************
- * Message header
- ******************************/
- struct message_head {
- unsigned int invalid_flag;
- unsigned int message_type;
- unsigned int child_type;
- unsigned int param_length;
- };
- /******************************
- * Fast call structures
- ******************************/
- struct create_NQ_struct {
- unsigned int n_t_nq_phy_addr;
- unsigned int n_t_size;
- unsigned int t_n_nq_phy_addr;
- unsigned int t_n_size;
- };
- struct create_vdrv_struct {
- unsigned int vdrv_type;
- unsigned int vdrv_phy_addr;
- unsigned int vdrv_size;
- };
- struct create_sys_ctl_struct {
- unsigned int sys_ctl_phy_addr;
- unsigned int sys_ctl_size;
- };
- struct ack_fast_call_struct {
- int retVal;
- };
- /*********************************
- * Standard call structures
- *********************************/
- struct std_msg_struct {
- unsigned int direction_flag;
- unsigned int meg_type;
- };
- #endif
- struct fdrv_call_struct {
- int fdrv_call_type;
- int fdrv_call_buff_size;
- int retVal;
- };
- #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
- unsigned long cpu_notify_flag = 0;
- static int current_cpu_id = 0x00;
- static int tz_driver_cpu_callback(struct notifier_block *nfb,
- unsigned long action, void *hcpu);
- static struct notifier_block tz_driver_cpu_notifer = {
- .notifier_call = tz_driver_cpu_callback,
- };
- 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;
- };
- struct smc_call_struct smc_call_entry;
- #define printk(fmt, args...) printk("\033[;34m[TEEI][TZDriver]"fmt"\033[0m", ##args)
- asmlinkage long sys_setpriority(int which, int who, int niceval);
- asmlinkage long sys_getpriority(int which, int who);
- static struct teei_contexts_head {
- u32 dev_file_cnt;
- struct list_head context_list;
- struct rw_semaphore teei_contexts_sem;
- } teei_contexts_head;
- struct teei_shared_mem_head {
- int shared_mem_cnt;
- struct list_head shared_mem_list;
- };
- struct tlog_struct {
- int valid;
- struct work_struct work;
- char context[TLOG_CONTEXT_LEN];
- };
- #if 0
- static int sub_pid;
- #else
- static struct task_struct *teei_fastcall_task;
- static struct task_struct *teei_switch_task;
- DEFINE_KTHREAD_WORKER(ut_fastcall_worker);
- #endif
- static struct cpumask mask = { CPU_BITS_NONE };
- int switch_enable_flag = 0;
- int forward_call_flag = 0;
- int irq_call_flag = 0;
- int fp_call_flag = 0;
- unsigned long sys_ctl_buffer = NULL;
- unsigned long vdrv_buffer = NULL;
- unsigned long teei_config_flag = 0;
- static struct tlog_struct tlog_ent[TLOG_MAX_CNT];
- unsigned int soter_error_flag = 0;
- DECLARE_COMPLETION(global_down_lock);
- EXPORT_SYMBOL_GPL(global_down_lock);
- extern int add_work_entry(int work_type, unsigned long buff);
- /*
- * structures and MACROs for NQ buffer
- */
- #define NQ_BUFF_SIZE (4096)
- #define NQ_BLOCK_SIZE (32)
- #define BLOCK_MAX_COUNT (NQ_BUFF_SIZE / NQ_BLOCK_SIZE - 1)
- #define STD_NQ_ACK_ID 0x01
- #define TEE_NAME_SIZE (255)
- #define START_STATUS (0)
- #define END_STATUS (1)
- #define VFS_SIZE (512 * 1024)
- #define FP_BUFF_SIZE (512 * 1024)
- static DEFINE_MUTEX(nt_t_NQ_lock);
- static DEFINE_MUTEX(t_nt_NQ_lock);
- struct semaphore smc_lock;
- //struct semaphore global_down_lock;
- struct semaphore api_lock;
- static int print_context(void);
- struct NQ_head {
- unsigned int start_index;
- unsigned int end_index;
- unsigned int Max_count;
- unsigned char reserve[20];
- };
- struct NQ_entry {
- unsigned int valid_flag;
- unsigned int length;
- unsigned int buffer_addr;
- unsigned char reserve[20];
- };
- static void *tz_malloc(size_t size, int flags)
- {
- void *ptr = kmalloc(size, flags|GFP_ATOMIC);
- return ptr;
- }
- void *tz_malloc_shared_mem(size_t size, int flags)
- {
- return (void *) __get_free_pages(flags, get_order(ROUND_UP(size, SZ_4K)));
- }
- void tz_free_shared_mem(void *addr, size_t size)
- {
- free_pages((unsigned long)addr, get_order(ROUND_UP(size, SZ_4K)));
- }
- static struct class *driver_class;
- static dev_t teei_client_device_no;
- static struct cdev teei_client_cdev;
- /* static u32 cacheline_size; */
- unsigned long device_file_cnt = 0;
- static struct teei_smc_cdata teei_smc_cd[NR_CPUS];
- struct semaphore boot_sema;
- struct semaphore fp_lock;
- unsigned long boot_vfs_addr;
- unsigned long boot_soter_flag;
- extern struct mutex pm_mutex;
- #if 1
- /*
- * structures for context & session management
- */
- struct teei_context {
- unsigned long cont_id; /* ID */
- char tee_name[TEE_NAME_SIZE]; /* Name */
- unsigned long sess_cnt; /* session counter */
- unsigned long shared_mem_cnt; /* share memory counter */
- struct list_head link; /* link list for teei_context */
- struct list_head sess_link; /* link list for the sessions of this context */
- struct list_head shared_mem_list; /* link list for the share memory of this context */
- struct semaphore cont_lock;
- };
- struct teei_session {
- int sess_id; /* ID */
- struct teei_context *parent_cont; /* the teei_context pointer of this session */
- struct list_head link; /* link list for teei_session */
- struct list_head encode_list; /* link list for the encode of this session */
- struct list_head shared_mem_list; /* link list for the share memory of this session */
- };
- struct teei_context *teei_create_context(int dev_count)
- {
- struct teei_context *cont = NULL;
- cont = kmalloc(sizeof(struct teei_context), GFP_KERNEL);
- if (cont == NULL)
- return NULL;
- cont->cont_id = dev_count;
- cont->sess_cnt = 0;
- memset(cont->tee_name, 0, TEE_NAME_SIZE);
- INIT_LIST_HEAD(&(cont->link));
- INIT_LIST_HEAD(&(cont->sess_link));
- INIT_LIST_HEAD(&(cont->shared_mem_list));
- list_add(&(cont->link), &(teei_contexts_head.context_list));
- teei_contexts_head.dev_file_cnt++;
- return cont;
- }
- struct teei_session *teei_create_session(struct teei_context *cont)
- {
- struct teei_session *sess = NULL;
- sess = kmalloc(sizeof(struct teei_session), GFP_KERNEL);
- if (sess == NULL)
- return NULL;
- sess->sess_id = (unsigned long)sess;
- sess->parent_cont = cont;
- INIT_LIST_HEAD(&(sess->link));
- INIT_LIST_HEAD(&(sess->encode_list));
- INIT_LIST_HEAD(&(sess->shared_mem_list));
- list_add(&(sess->link), &(cont->sess_link));
- cont->sess_cnt = cont->sess_cnt + 1;
- return sess;
- }
- /*add by microtrust*/
- static unsigned int get_master_cpu_id(unsigned int gic_irqs)
- {
- unsigned int i;
- i = gic_irqs >> 2;
- unsigned long gic_base = 0x10231000 + 0x800 + i * 4 ;
- void __iomem *dist_base = (void __iomem *)gic_base;
- unsigned int target_id = readl_relaxed(dist_base);
- target_id = target_id >> ((gic_irqs & 0x03) * 8);
- target_id = target_id & 0xff;
- return target_id;
- }
- /*****************************************/
- /*extern u32 get_irq_target_microtrust(void);*/
- int get_current_cpuid(void)
- {
- return current_cpu_id;
- }
- static void secondary_nt_sched_t(void *info)
- {
- nt_sched_t();
- }
- void nt_sched_t_call(void)
- {
- #if 0
- nt_sched_t();
- #else
- int cpu_id = 0;
- #if 0
- get_online_cpus();
- cpu_id = get_current_cpuid();
- smp_call_function_single(cpu_id, secondary_nt_sched_t, NULL, 1);
- put_online_cpus();
- #else
- int retVal = 0;
- retVal = add_work_entry(SCHED_CALL, NULL);
- if (retVal != 0) {
- printk("[%s][%d] add_work_entry function failed!\n", __func__, __LINE__);
- }
- #endif
- #endif
- return;
- }
- /*********************************************************************************
- * global_fn Global schedule thread function.
- *
- * switch_enable_flag: Waiting for the n_switch_to_t_os_stage2 finished
- * forward_call_flag: Forward direction call flag
- *
- *********************************************************************************/
- int global_fn(void)
- {
- int retVal = 0;
- /* forward_call_flag = GLSCH_NONE; */
- while (1) {
- #if 0
- if ((forward_call_flag == GLSCH_NONE) && (fp_call_flag == GLSCH_NONE)) {
- set_freezable();
- set_current_state(TASK_INTERRUPTIBLE);
- } else {
- set_nofreezable();
- set_current_state(TASK_UNINTERRUPTIBLE);
- }
- #else
- set_freezable();
- set_current_state(TASK_INTERRUPTIBLE);
- #endif
- if (teei_config_flag == 1) {
- retVal = wait_for_completion_interruptible(&global_down_lock);
- if (retVal == -ERESTARTSYS) {
- printk("[%s][%d]*********down &global_down_lock failed *****************\n", __func__, __LINE__ );
- continue;
- }
- }
- /* down(&smc_lock); */
- retVal = down_interruptible(&smc_lock);
- if (retVal != 0) {
- printk("[%s][%d]*********down &smc_lock failed *****************\n", __func__, __LINE__ );
- complete(&global_down_lock);
- continue;
- }
- 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 {
- up(&smc_lock);
- 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 {
- up(&smc_lock);
- msleep_interruptible(1);
- }
- } else {
- /* printk("[%s][%d]**************************\n", __func__, __LINE__ ); */
- up(&smc_lock);
- msleep_interruptible(1);
- }
- }
- }
- struct teei_encode {
- struct list_head head;
- int encode_id;
- void *ker_req_data_addr;
- void *ker_res_data_addr;
- u32 enc_req_offset;
- u32 enc_res_offset;
- u32 enc_req_pos;
- u32 enc_res_pos;
- u32 dec_res_pos;
- u32 dec_offset;
- struct teei_encode_meta *meta;
- };
- struct teei_shared_mem {
- struct list_head head;
- struct list_head s_head;
- void *index;
- void *k_addr;
- void *u_addr;
- u32 len;
- };
- static int teei_client_prepare_encode(void *private_data,
- struct teei_client_encode_cmd *enc,
- struct teei_encode **penc_context,
- struct teei_session **psession);
- /******************************************************************************/
- static void post_smc_work(u32 cmd_addr);
- static void init_smc_work(void);
- struct tz_work_entry {
- u32 cmd_addr;
- struct work_struct work;
- };
- static struct work_queue *tz_wq;
- static struct tz_work_entry tz_work_ent;
- struct semaphore tz_sem;
- static void tz_work_func(struct work_struct *entry)
- {
- struct tz_work_entry *md = container_of(entry, struct tz_work_entry, work);
- #if 0
- /* disable touchscreen interrupt */
- disable_irq_nosync(350);
- printk("=====TZ DISABLE================\n");
- n_send_mem_info_to_ta(md->cmd_addr, sizeof(struct teei_smc_cmd));
- /* enable touchscreen interrupt */
- enable_irq(350);
- printk("======TZ ENABLE================\n");
- #endif
- up(&tz_sem);
- }
- static void post_smc_work(u32 cmd_addr)
- {
- tz_work_ent.cmd_addr = cmd_addr;
- INIT_WORK(&(tz_work_ent.work), tz_work_func);
- queue_work(tz_wq, &(tz_work_ent.work));
- down(&tz_sem);
- wait_for_service_done();
- }
- static void init_smc_work(void)
- {
- sema_init(&tz_sem, 0);
- tz_wq = create_workqueue("TZ SMC WORK");
- }
- /**
- * @brief
- *
- * @param cmd_addr phys address
- *
- * @return
- */
- static u32 _teei_smc(u32 cmd_addr, int size, int valid_flag)
- {
- int i = 0;
- #if 1
- /* disable touchscreen interrupt */
- add_nq_entry(cmd_addr, size, valid_flag);
- set_sch_nq_cmd();
- Flush_Dcache_By_Area((unsigned long)t_nt_buffer, (unsigned long)t_nt_buffer + 0x1000);
- n_invoke_t_nq(0, 0, 0);
- #else
- post_smc_work(cmd_addr);
- #endif
- return 0;
- }
- /**
- * @brief
- *
- * @param teei_smc handler for secondary cores
- *
- * @return
- */
- static void secondary_teei_smc_handler(void *info)
- {
- struct teei_smc_cdata *cd = (struct teei_smc_cdata *)info;
- /* with a rmb() */
- rmb();
- TDEBUG("secondary teei smc handler...");
- cd->ret_val = _teei_smc(cd->cmd_addr, cd->size, cd->valid_flag);
- /* with a wmb() */
- wmb();
- TDEBUG("done smc on primary ");
- }
- /**
- * @brief
- *
- * @param This function takes care of posting the smc to the
- * primary core
- *
- * @return
- */
- static u32 post_teei_smc(int cpu_id, u32 cmd_addr, int size, int valid_flag)
- {
- struct teei_smc_cdata *cd = &teei_smc_cd[cpu_id];
- TDEBUG("Post from secondary ...");
- cd->cmd_addr = cmd_addr;
- cd->size = size;
- cd->valid_flag = valid_flag;
- cd->ret_val = 0;
- /* with a wmb() */
- wmb();
- get_online_cpus();
- smp_call_function_single(cpu_id, secondary_teei_smc_handler, (void *)cd, 1);
- put_online_cpus();
- /* with a rmb() */
- rmb();
- TDEBUG("completed smc on secondary ");
- return cd->ret_val;
- }
- /**
- * @brief
- *
- * @param teei_smc wrapper to handle the multi core case
- *
- * @return
- */
- static u32 teei_smc(u32 cmd_addr, int size, int valid_flag)
- {
- #if 0
- int cpu_id = smp_processor_id();
- /* int cpu_id = raw_smp_processor_id(); */
- if (cpu_id != 0) {
- /* with mb */
- mb();
- printk("[%s][%d]\n", __func__, __LINE__);
- return post_teei_smc(0, cmd_addr, size, valid_flag); /* post it to primary */
- } else {
- printk("[%s][%d]\n", __func__, __LINE__);
- return _teei_smc(cmd_addr, size, valid_flag); /* called directly on primary core */
- }
- #else
- return _teei_smc(cmd_addr, size, valid_flag);
- /* return post_teei_smc(0, cmd_addr, size, valid_flag); */
- #endif
- }
- /**
- * @brief
- * call smc
- * @param svc_id - service identifier
- * @param cmd_id - command identifier
- * @param context - session context
- * @param enc_id - encoder identifier
- * @param cmd_buf - command buffer
- * @param cmd_len - command buffer length
- * @param resp_buf - response buffer
- * @param resp_len - response buffer length
- * @param meta_data
- * @param ret_resp_len
- *
- * @return
- */
- 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)
- {
- int ret = 50;
- void *smc_cmd_phys = 0;
- struct teei_smc_cmd *smc_cmd = NULL;
- struct teei_shared_mem *temp_shared_mem = NULL;
- struct teei_context *temp_cont = NULL;
- #if 0
- smc_cmd = (struct teei_smc_cmd *)tz_malloc_shared_mem(sizeof(struct teei_smc_cmd), GFP_KERNEL | GFP_DMA);
- if (!smc_cmd) {
- TERR("tz_malloc failed for smc command");
- ret = -ENOMEM;
- goto out;
- }
- #else
- smc_cmd = (struct teei_smc_cmd *)local_smc_cmd;
- #endif
- if (ret_resp_len)
- *ret_resp_len = 0;
- smc_cmd->teei_cmd_type = teei_cmd_type;
- smc_cmd->dev_file_id = dev_file_id;
- smc_cmd->src_id = svc_id;
- smc_cmd->src_context = task_tgid_vnr(current);
- smc_cmd->id = cmd_id;
- smc_cmd->context = context;
- smc_cmd->enc_id = enc_id;
- smc_cmd->src_context = task_tgid_vnr(current);
- smc_cmd->req_buf_len = cmd_len;
- smc_cmd->resp_buf_len = resp_len;
- smc_cmd->info_buf_len = info_len;
- smc_cmd->ret_resp_buf_len = 0;
- if (NULL == psema)
- return -EINVAL;
- else
- smc_cmd->teei_sema = psema;
- if (cmd_buf != NULL) {
- smc_cmd->req_buf_phys = virt_to_phys((void *)cmd_buf);
- Flush_Dcache_By_Area((unsigned long)cmd_buf, (unsigned long)cmd_buf + cmd_len);
- Flush_Dcache_By_Area((unsigned long)&cmd_buf, (unsigned long)&cmd_buf + sizeof(int));
- } else
- smc_cmd->req_buf_phys = 0;
- if (resp_buf) {
- smc_cmd->resp_buf_phys = virt_to_phys((void *)resp_buf);
- Flush_Dcache_By_Area((unsigned long)resp_buf, (unsigned long)resp_buf + resp_len);
- } else
- smc_cmd->resp_buf_phys = 0;
- if (meta_data) {
- smc_cmd->meta_data_phys = virt_to_phys(meta_data);
- Flush_Dcache_By_Area((unsigned long)meta_data, (unsigned long)meta_data +
- sizeof(struct teei_encode_meta) * (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS));
- } else
- smc_cmd->meta_data_phys = 0;
- if (info_data) {
- smc_cmd->info_buf_phys = virt_to_phys(info_data);
- Flush_Dcache_By_Area((unsigned long)info_data, (unsigned long)info_data + info_len);
- } else
- smc_cmd->info_buf_phys = 0;
- smc_cmd_phys = virt_to_phys((void *)smc_cmd);
- smc_cmd->error_code = 0;
- Flush_Dcache_By_Area((unsigned long)smc_cmd, (unsigned long)smc_cmd + sizeof(struct teei_smc_cmd));
- Flush_Dcache_By_Area((unsigned long)&smc_cmd, (unsigned long)&smc_cmd + sizeof(int));
- /* down(&smc_lock); */
- list_for_each_entry(temp_cont,
- &teei_contexts_head.context_list,
- link) {
- if (temp_cont->cont_id == dev_file_id) {
- list_for_each_entry(temp_shared_mem,
- &temp_cont->shared_mem_list,
- head) {
- Flush_Dcache_By_Area((unsigned long)temp_shared_mem->k_addr, (unsigned long)temp_shared_mem->k_addr + temp_shared_mem->len);
- }
- }
- }
- forward_call_flag = GLSCH_LOW;
- ret = teei_smc(smc_cmd_phys, sizeof(struct teei_smc_cmd), NQ_VALID);
- /* down(psema); */
- #if 0
- Invalidate_Dcache_By_Area((unsigned long)smc_cmd, (unsigned long)smc_cmd + sizeof(struct teei_smc_cmd));
- if (cmd_buf)
- Invalidate_Dcache_By_Area((unsigned long)cmd_buf, (unsigned long)cmd_buf + cmd_len);
- if (resp_buf)
- Invalidate_Dcache_By_Area((unsigned long)resp_buf, (unsigned long)resp_buf + resp_len);
- if (meta_data)
- Invalidate_Dcache_By_Area((unsigned long)meta_data, (unsigned long)meta_data +
- sizeof(struct teei_encode_meta) * (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS));
- if (info_data)
- Invalidate_Dcache_By_Area((unsigned long)info_data, (unsigned long)info_data + info_len);
- if (error_code)
- *error_code = smc_cmd->error_code;
- if (ret) {
- printk("[%s][%d] smc_call returns error!\n", __func__, __LINE__);
- goto out;
- }
- if (ret_resp_len)
- *ret_resp_len = smc_cmd->ret_resp_buf_len;
- out:
- if (smc_cmd)
- tz_free_shared_mem(smc_cmd, sizeof(struct teei_smc_cmd));
- return ret;
- #endif
- return 0;
- }
- #if 1
- static void secondary_teei_smc_call(void *info)
- {
- struct smc_call_struct *cd = (struct smc_call_struct *)info;
- /* with a rmb() */
- rmb();
- TDEBUG("secondary teei smc call...");
- if (cd->cmd_buf != NULL) {
- /* Flush_Dcache_By_Area((unsigned long)(cd->cmd_buf), (unsigned long)(cd->cmd_buf) + cd->cmd_len);*/
- }
- if (cd->resp_buf != NULL) {
- /* Flush_Dcache_By_Area((unsigned long)(cd->resp_buf), (unsigned long)(cd->resp_buf) + cd->resp_len);*/
- }
- if (cd->meta_data != NULL) {
- /* Flush_Dcache_By_Area((unsigned long)(cd->meta_data), (unsigned long)(cd->meta_data) +
- sizeof(struct teei_encode_meta) * (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS));*/
- }
- if (cd->info_data != NULL) {
- /* Flush_Dcache_By_Area((unsigned long)(cd->info_data), (unsigned long)(cd->info_data) + cd->info_len);*/
- }
- 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();
- TDEBUG("done smc on primary ");
- }
- int teei_smc_call(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)
- {
- int cpu_id = 0;
- int retVal = 0;
- struct teei_smc_cmd *local_smc_cmd = (struct teei_smc_cmd *)tz_malloc_shared_mem(sizeof(struct teei_smc_cmd), GFP_KERNEL | GFP_DMA);
- if (local_smc_cmd == NULL) {
- printk("[%s][%d] tz_malloc_shared_mem failed!\n", __func__, __LINE__);
- return -1;
- }
- smc_call_entry.local_cmd = local_smc_cmd;
- smc_call_entry.teei_cmd_type = teei_cmd_type;
- smc_call_entry.dev_file_id = dev_file_id;
- smc_call_entry.svc_id = svc_id;
- smc_call_entry.cmd_id = cmd_id;
- smc_call_entry.context = context;
- smc_call_entry.enc_id = enc_id;
- smc_call_entry.cmd_buf = cmd_buf;
- smc_call_entry.cmd_len = cmd_len;
- smc_call_entry.resp_buf = resp_buf;
- smc_call_entry.resp_len = resp_len;
- smc_call_entry.meta_data = meta_data;
- smc_call_entry.info_data = info_data;
- smc_call_entry.info_len = info_len;
- smc_call_entry.ret_resp_len = ret_resp_len;
- smc_call_entry.error_code = error_code;
- smc_call_entry.psema = psema;
- if (teei_config_flag == 1) {
- complete(&global_down_lock);
- }
- down(&smc_lock);
- /* with a wmb() */
- wmb();
- #if 0
- get_online_cpus();
- cpu_id = get_current_cpuid();
- smp_call_function_single(cpu_id, secondary_teei_smc_call, (void *)(&smc_call_entry), 1);
- put_online_cpus();
- #else
- Flush_Dcache_By_Area((unsigned long)&smc_call_entry, (unsigned long)&smc_call_entry + sizeof(smc_call_entry));
- retVal = add_work_entry(CAPI_CALL, (unsigned long)&smc_call_entry);
- if (retVal != 0) {
- tz_free_shared_mem(local_smc_cmd, sizeof(struct teei_smc_cmd));
- return retVal;
- }
- #endif
- down(psema);
- rmb();
- if (ret_resp_len)
- *ret_resp_len = local_smc_cmd->ret_resp_buf_len;
- tz_free_shared_mem(local_smc_cmd, sizeof(struct teei_smc_cmd));
- return smc_call_entry.retVal;
- }
- #endif
- int service_smc_call(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,
- int *ret_resp_len,
- void *wq,
- void *arg_lock, int *error_code)
- {
- return 0;
- }
- static int teei_client_close_session_for_service(
- void *private_data,
- struct teei_session *temp_ses)
- {
- struct ser_ses_id *ses_close = (struct ser_ses_id *)tz_malloc_shared_mem(sizeof(struct ser_ses_id), GFP_KERNEL | GFP_DMA );
- struct teei_context *curr_cont = NULL;
- struct teei_encode *temp_encode = NULL;
- struct teei_encode *enc_context = NULL;
- struct teei_shared_mem *shared_mem = NULL;
- struct teei_shared_mem *temp_shared = NULL;
- unsigned long dev_file_id = (unsigned long)private_data;
- int retVal = 0;
- int *res = (int *)tz_malloc_shared_mem(4, GFP_KERNEL | GFP_DMA);
- int error_code = 0;
- if (temp_ses == NULL)
- return -EINVAL;
- if (ses_close == NULL)
- return -ENOMEM;
- if (res == NULL)
- return -ENOMEM;
- ses_close->session_id = temp_ses->sess_id;
- printk("======== ses_close->session_id = %d =========\n", ses_close->session_id);
- curr_cont = temp_ses->parent_cont;
- retVal = teei_smc_call(TEEI_CMD_TYPE_CLOSE_SESSION,
- dev_file_id,
- 0,
- TEEI_GLOBAL_CMD_ID_CLOSE_SESSION,
- 0,
- 0,
- ses_close,
- sizeof(struct ser_ses_id),
- res,
- sizeof(int),
- NULL,
- NULL,
- 0,
- NULL,
- &error_code,
- &(curr_cont->cont_lock));
- if (!list_empty(&temp_ses->encode_list)) {
- list_for_each_entry_safe(enc_context,
- temp_encode,
- &temp_ses->encode_list,
- head) {
- if (enc_context) {
- list_del(&enc_context->head);
- kfree(enc_context);
- }
- }
- }
- if (!list_empty(&temp_ses->shared_mem_list)) {
- list_for_each_entry_safe(shared_mem,
- temp_shared,
- &temp_ses->shared_mem_list,
- s_head) {
- if (shared_mem == NULL)
- continue;
- list_del(&shared_mem->s_head);
- if (shared_mem->k_addr)
- free_pages((unsigned long)shared_mem->k_addr,
- get_order(ROUND_UP(shared_mem->len, SZ_4K)));
- kfree(shared_mem);
- }
- }
- list_del(&temp_ses->link);
- curr_cont->sess_cnt = curr_cont->sess_cnt - 1;
- kfree(temp_ses);
- tz_free_shared_mem(res, 4);
- tz_free_shared_mem(ses_close, sizeof(struct ser_ses_id));
- return 0;
- }
- static int teei_client_service_init(struct teei_context *dev_file, struct ser_ses_id *ses_open)
- {
- return 0;
- }
- /**
- * @brief close the context with context_ID equal private_data
- *
- * @return EINVAL: Can not find the context with ID equal private_data
- * 0: success
- */
- static int teei_client_service_exit(void *private_data)
- {
- struct teei_shared_mem *temp_shared_mem = NULL;
- struct teei_shared_mem *temp_pos = NULL;
- struct teei_context *temp_context = NULL;
- struct teei_context *temp_context_pos = NULL;
- struct teei_session *temp_ses = NULL;
- struct teei_session *temp_ses_pos = NULL;
- unsigned long dev_file_id = 0;
- dev_file_id = (unsigned long)(private_data);
- down_write(&(teei_contexts_head.teei_contexts_sem));
- list_for_each_entry_safe(temp_context,
- temp_context_pos,
- &teei_contexts_head.context_list,
- link) {
- if (temp_context->cont_id == dev_file_id) {
- list_for_each_entry_safe(temp_shared_mem,
- temp_pos,
- &temp_context->shared_mem_list,
- head) {
- if (temp_shared_mem) {
- list_del(&(temp_shared_mem->head));
- if (temp_shared_mem->k_addr) {
- free_pages((unsigned long)temp_shared_mem->k_addr,
- get_order(ROUND_UP(temp_shared_mem->len, SZ_4K)));
- }
- kfree(temp_shared_mem);
- }
- }
- if (!list_empty(&temp_context->sess_link)) {
- list_for_each_entry_safe(temp_ses,
- temp_ses_pos,
- &temp_context->sess_link,
- link)
- teei_client_close_session_for_service(private_data, temp_ses);
- }
- list_del(&temp_context->link);
- kfree(temp_context);
- up_write(&(teei_contexts_head.teei_contexts_sem));
- return 0;
- }
- }
- return -EINVAL;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_session_init(void *private_data, void *argp)
- {
- struct teei_context *temp_cont = NULL;
- struct teei_session *ses_new = NULL;
- struct user_ses_init ses_init;
- int ctx_found = 0;
- unsigned long dev_file_id = (unsigned long)private_data;
- TDEBUG("inside session init");
- if (copy_from_user(&ses_init, argp, sizeof(ses_init))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- down_read(&(teei_contexts_head.teei_contexts_sem));
- /*print_context();*/
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- ctx_found = 1;
- break;
- }
- }
- up_read(&(teei_contexts_head.teei_contexts_sem));
- if (!ctx_found) {
- printk("[%s][%d] can't find context.\n", __func__, __LINE__);
- return -EINVAL;
- }
- ses_new = (struct teei_session *)tz_malloc(sizeof(struct teei_session), GFP_KERNEL);
- if (ses_new == NULL) {
- printk("[%s][%d] tz_malloc failed.\n", __func__, __LINE__);
- return -ENOMEM;
- }
- ses_init.session_id = (unsigned long)ses_new;
- ses_new->sess_id = (unsigned long)ses_new;
- ses_new->parent_cont = temp_cont;
- INIT_LIST_HEAD(&ses_new->link);
- INIT_LIST_HEAD(&ses_new->encode_list);
- INIT_LIST_HEAD(&ses_new->shared_mem_list);
- list_add_tail(&ses_new->link, &temp_cont->sess_link);
- if (copy_to_user(argp, &ses_init, sizeof(ses_init))) {
- list_del(&ses_new->link);
- kfree(ses_new);
- return -EFAULT;
- }
- return 0;
- }
- /**
- * @brief Open one session
- *
- * @param argp
- *
- * @return 0: success
- * EFAULT: copy data from user space OR copy data back to the user space error
- * EINVLA: can not find the context OR session structure.
- */
- static int teei_client_session_open(void *private_data, void *argp)
- {
- struct teei_context *temp_cont = NULL;
- struct teei_session *ses_new = NULL;
- struct teei_encode *enc_temp = NULL;
- struct ser_ses_id *ses_open = (struct ser_ses_id *)tz_malloc_shared_mem(sizeof(struct ser_ses_id), GFP_KERNEL | GFP_DMA );
- int ctx_found = 0;
- int sess_found = 0;
- int enc_found = 0;
- int retVal = 0;
- unsigned long dev_file_id = (unsigned long)private_data;
- printk("ses open [%ld]\n", (unsigned long)ses_open);
- if (ses_open == NULL) {
- return -EFAULT;
- }
- /* Get the paraments about this session from user space. */
- if (copy_from_user(ses_open, argp, sizeof(struct ser_ses_id))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- tz_free_shared_mem(ses_open, sizeof(struct ser_ses_id));
- return -EFAULT;
- }
- /* Search the teei_context structure */
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- ctx_found = 1;
- break;
- }
- }
- if (ctx_found == 0) {
- printk("[%s][%d] can't find context!\n", __func__, __LINE__);
- tz_free_shared_mem(ses_open, sizeof(struct ser_ses_id));
- return -EINVAL;
- }
- /* Search the teei_session structure */
- list_for_each_entry(ses_new, &temp_cont->sess_link, link) {
- if (ses_new->sess_id == ses_open->session_id) {
- sess_found = 1;
- break;
- }
- }
- if (sess_found == 0) {
- printk("[%s][%d] can't find session!\n", __func__, __LINE__);
- tz_free_shared_mem(ses_open, sizeof(struct ser_ses_id));
- return -EINVAL;
- }
- /* Search the teei_encode structure */
- list_for_each_entry(enc_temp, &ses_new->encode_list, head) {
- if (enc_temp->encode_id == ses_open->paramtype) {
- enc_found = 1;
- break;
- }
- }
- /* Invoke the smc_call */
- if (enc_found) {
- /* This session had been encoded. */
- retVal = teei_smc_call(TEEI_CMD_TYPE_OPEN_SESSION,
- dev_file_id,
- 0,
- 0,
- 0,
- 0,
- enc_temp->ker_req_data_addr,
- enc_temp->enc_req_offset,
- enc_temp->ker_res_data_addr,
- enc_temp->enc_res_offset,
- enc_temp->meta,
- ses_open,
- sizeof(struct ser_ses_id),
- NULL,
- NULL,
- &(temp_cont->cont_lock));
- } else {
- /* This session didn't have been encoded */
- retVal = teei_smc_call(TEEI_CMD_TYPE_OPEN_SESSION,
- dev_file_id,
- 0,
- 0,
- 0,
- 0,
- NULL,
- 0,
- NULL,
- 0,
- NULL,
- ses_open,
- sizeof(struct ser_ses_id),
- NULL,
- NULL,
- &(temp_cont->cont_lock));
- }
- if (retVal != SMC_SUCCESS) {
- printk("[%s][%d] open session smc error!\n", __func__, __LINE__);
- goto clean_hdr_buf;
- }
- if (ses_open->session_id == -1)
- printk("[%s][%d] invalid session id!\n", __func__, __LINE__);
- /* Copy the result back to the user space */
- ses_new->sess_id = ses_open->session_id;
- if (copy_to_user(argp, ses_open, sizeof(struct ser_ses_id))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- retVal = -EFAULT;
- goto clean_hdr_buf;
- }
- tz_free_shared_mem(ses_open, sizeof(struct ser_ses_id));
- return 0;
- clean_hdr_buf:
- list_del(&ses_new->link);
- tz_free_shared_mem(ses_open, sizeof(struct ser_ses_id));
- kfree(ses_new);
- return retVal;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_session_close(void *private_data, void *argp)
- {
- struct teei_context *temp_cont = NULL;
- struct teei_session *temp_ses = NULL;
- int retVal = -EFAULT;
- unsigned long dev_file_id = (unsigned long)private_data;
- struct ser_ses_id ses_close;
- if (copy_from_user(&ses_close, argp, sizeof(ses_close))) {
- printk("[%s][%d] copy from user failed.\n ", __func__, __LINE__);
- return -EFAULT;
- }
- down_read(&(teei_contexts_head.teei_contexts_sem));
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- list_for_each_entry(temp_ses, &temp_cont->sess_link, link) {
- if (temp_ses->sess_id == ses_close.session_id) {
- teei_client_close_session_for_service(private_data, temp_ses);
- retVal = 0;
- goto copy_to_user;
- }
- }
- }
- }
- copy_to_user:
- up_read(&(teei_contexts_head.teei_contexts_sem));
- if (copy_to_user(argp, &ses_close, sizeof(ses_close))) {
- printk("[%s][%d] copy from user failed.\n", __func__, __LINE__);
- return -EFAULT;
- }
- return retVal;
- }
- /**
- * @brief Map the vma with the free pages
- *
- * @param filp
- * @param vma
- *
- * @return 0: success
- * EINVAL: Invalid parament
- * ENOMEM: No enough memory
- */
- static int teei_client_mmap(struct file *filp, struct vm_area_struct *vma)
- {
- int retVal = 0;
- struct teei_shared_mem *share_mem_entry = NULL;
- int context_found = 0;
- unsigned long alloc_addr = 0;
- struct teei_context *cont = NULL;
- long length = vma->vm_end - vma->vm_start;
- /* Reasch the context with ID equal filp->private_data */
- down_read(&(teei_contexts_head.teei_contexts_sem));
- list_for_each_entry(cont, &(teei_contexts_head.context_list), link) {
- if (cont->cont_id == (unsigned long)filp->private_data) {
- context_found = 1;
- break;
- }
- }
- if (context_found == 0) {
- up_read(&(teei_contexts_head.teei_contexts_sem));
- return -EINVAL;
- }
- /* Alloc one teei_share_mem structure */
- share_mem_entry = tz_malloc(sizeof(struct teei_shared_mem), GFP_KERNEL);
- if (share_mem_entry == NULL) {
- printk("[%s][%d] tz_malloc failed!\n", __func__, __LINE__);
- up_read(&(teei_contexts_head.teei_contexts_sem));
- return -ENOMEM;
- }
- /* Get free pages from Kernel. */
- alloc_addr = (unsigned long) __get_free_pages(GFP_KERNEL | GFP_DMA , get_order(ROUND_UP(length, SZ_4K)));
- if (alloc_addr == 0) {
- printk("[%s][%d] get free pages failed!\n", __func__, __LINE__);
- kfree(share_mem_entry);
- up_read(&(teei_contexts_head.teei_contexts_sem));
- return -ENOMEM;
- }
- /* Remap the free pages to the VMA */
- retVal = remap_pfn_range(vma, vma->vm_start, ((virt_to_phys((void *)alloc_addr)) >> PAGE_SHIFT),
- length, vma->vm_page_prot);
- if (retVal) {
- printk("[%s][%d] remap_pfn_range failed!\n", __func__, __LINE__);
- kfree(share_mem_entry);
- free_pages(alloc_addr, get_order(ROUND_UP(length, SZ_4K)));
- up_read(&(teei_contexts_head.teei_contexts_sem));
- return retVal;
- }
- /* Add the teei_share_mem into the teei_context struct */
- share_mem_entry->k_addr = (void *)alloc_addr;
- share_mem_entry->len = length;
- share_mem_entry->u_addr = (void *)vma->vm_start;
- share_mem_entry->index = share_mem_entry->u_addr;
- cont->shared_mem_cnt++;
- list_add_tail(&(share_mem_entry->head), &(cont->shared_mem_list));
- up_read(&(teei_contexts_head.teei_contexts_sem));
- return 0;
- }
- /**
- * @brief Send a command to TEE
- *
- * @param argp
- *
- * @return EINVAL: Invalid parament
- * EFAULT: copy data from user space OR copy data back to the user space error
- * 0: success
- */
- static int teei_client_send_cmd(void *private_data, void *argp)
- {
- int retVal = 0;
- struct teei_client_encode_cmd enc;
- unsigned long dev_file_id = 0;
- struct teei_context *temp_cont = NULL;
- struct teei_session *temp_ses = NULL;
- struct teei_encode *enc_temp = NULL;
- int ctx_found = 0;
- int sess_found = 0;
- int enc_found = 0;
- dev_file_id = (unsigned long)private_data;
- if (copy_from_user(&enc, argp, sizeof(enc))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- down_read(&(teei_contexts_head.teei_contexts_sem));
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- ctx_found = 1;
- break;
- }
- }
- up_read(&(teei_contexts_head.teei_contexts_sem));
- if (ctx_found == 0) {
- printk("[%s][%d] can't find context data!\n", __func__, __LINE__);
- return -EINVAL;
- }
- list_for_each_entry(temp_ses, &temp_cont->sess_link, link) {
- if (temp_ses->sess_id == enc.session_id) {
- sess_found = 1;
- break;
- }
- }
- if (sess_found == 0) {
- printk("[%s][%d] can't find session data!\n", __func__, __LINE__);
- return -EINVAL;
- }
- if (enc.encode_id != -1) {
- list_for_each_entry(enc_temp, &temp_ses->encode_list, head) {
- if (enc_temp->encode_id == enc.encode_id) {
- enc_found = 1;
- break;
- }
- }
- } else {
- retVal = teei_client_prepare_encode(private_data, &enc, &enc_temp, &temp_ses);
- if (retVal == 0)
- enc_found = 1;
- }
- if (enc_found == 0) {
- printk("[%s][%d] can't find encode data!\n", __func__, __LINE__);
- return -EINVAL;
- }
- retVal = teei_smc_call(TEEI_CMD_TYPE_INVOKE_COMMAND,
- dev_file_id,
- 0,
- enc.cmd_id,
- enc.session_id,
- enc.encode_id,
- enc_temp->ker_req_data_addr,
- enc_temp->enc_req_offset,
- enc_temp->ker_res_data_addr,
- enc_temp->enc_res_offset,
- enc_temp->meta,
- NULL,
- 0,
- &enc.return_value,
- &enc.return_origin,
- &(temp_cont->cont_lock));
- if (retVal != SMC_SUCCESS)
- printk("[%s][%d] send cmd secure call failed!\n", __func__, __LINE__);
- if (copy_to_user(argp, &enc, sizeof(enc))) {
- printk("[%s][%d] copy to user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- return retVal;
- }
- static int teei_client_context_init(void *private_data, void *argp)
- {
- int retVal = 0;
- struct teei_context *temp_cont = NULL;
- unsigned long dev_file_id = (unsigned long)private_data;
- struct ctx_data ctx;
- int dev_found = 0;
- int error_code = 0;
- int *resp_flag = tz_malloc_shared_mem(4, GFP_KERNEL | GFP_DMA);
- char *name = tz_malloc_shared_mem(sizeof(ctx.name), GFP_KERNEL | GFP_DMA);
- if (resp_flag == NULL)
- return -ENOMEM;
- if (name == NULL)
- return -ENOMEM;
- if (copy_from_user(&ctx, argp, sizeof(ctx))) {
- printk("[%s][%d] copy from user failed.\n ", __func__, __LINE__);
- return -EFAULT;
- }
- memcpy(name, ctx.name, sizeof(ctx.name));
- printk("[%s][%d] context name = %s.\n ", __func__, __LINE__, name);
- Flush_Dcache_By_Area((unsigned long)name,
- (unsigned long)name+sizeof(ctx.name));
- down_write(&(teei_contexts_head.teei_contexts_sem));
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- dev_found = 1;
- break;
- }
- }
- up_write(&(teei_contexts_head.teei_contexts_sem));
- if (dev_found) {
- strcpy(temp_cont->tee_name, ctx.name);
- retVal = teei_smc_call(TEEI_CMD_TYPE_INITILIZE_CONTEXT, dev_file_id,
- 0, 0, 0, 0, name, 255, resp_flag, 4, NULL,
- NULL, 0, NULL, &error_code, &(temp_cont->cont_lock));
- }
- ctx.ctx_ret = !(*resp_flag);
- tz_free_shared_mem(resp_flag, 4);
- tz_free_shared_mem(name, sizeof(ctx.name));
- if (copy_to_user(argp, &ctx, sizeof(ctx))) {
- printk("[%s][%d]copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- return retVal;
- }
- static int teei_client_context_close(void *private_data, void *argp)
- {
- int retVal = 0;
- struct teei_context *temp_cont = NULL;
- unsigned long dev_file_id = (unsigned long)private_data;
- struct ctx_data ctx;
- int dev_found = 0;
- int *resp_flag = (int *) tz_malloc_shared_mem(4, GFP_KERNEL | GFP_DMA);
- int error_code = 0;
- if (resp_flag == NULL)
- return -ENOMEM;
- if (copy_from_user(&ctx, argp, sizeof(ctx))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- down_write(&(teei_contexts_head.teei_contexts_sem));
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- printk("cont_id = %ld =======\n", temp_cont->cont_id);
- if (temp_cont->cont_id == dev_file_id) {
- dev_found = 1;
- break;
- }
- }
- up_write(&(teei_contexts_head.teei_contexts_sem));
- if (dev_found) {
- strcpy(temp_cont->tee_name, ctx.name);
- retVal = teei_smc_call(TEEI_CMD_TYPE_FINALIZE_CONTEXT, dev_file_id,
- 0, 0, 0, 0,
- NULL, 0, resp_flag, 4, NULL, NULL,
- 0, NULL, &error_code, &(temp_cont->cont_lock));
- }
- ctx.ctx_ret = *resp_flag;
- tz_free_shared_mem(resp_flag, 4);
- if (copy_to_user(argp, &ctx, sizeof(ctx))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- return retVal;
- }
- /**
- * @brief Delete the operation with the encode_id
- *
- * @param argp
- *
- * @return EINVAL: Invalid parament
- * EFAULT: copy data from user space OR copy data back to the user space error
- * 0: success
- */
- static int teei_client_operation_release(void *private_data, void *argp)
- {
- struct teei_client_encode_cmd enc;
- struct teei_encode *enc_context = NULL;
- struct teei_context *temp_cont = NULL;
- struct teei_session *temp_ses = NULL;
- int ctx_found = 0;
- int session_found = 0;
- int enc_found = 0;
- unsigned long dev_file_id = (unsigned long)private_data;
- if (copy_from_user(&enc, argp, sizeof(enc))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- ctx_found = 1;
- break;
- }
- }
- if (ctx_found == 0) {
- printk("[%s][%d] ctx_found failed!\n", __func__, __LINE__);
- return -EINVAL;
- }
- list_for_each_entry(temp_ses, &temp_cont->sess_link, link) {
- if (temp_ses->sess_id == enc.session_id) {
- session_found = 1;
- break;
- }
- }
- if (session_found == 0) {
- printk("[%s][%d] session_found failed!\n", __func__, __LINE__);
- return -EINVAL;
- }
- if (enc.encode_id != -1) {
- list_for_each_entry(enc_context, &temp_ses->encode_list, head) {
- if (enc_context->encode_id == enc.encode_id) {
- enc_found = 1;
- break;
- }
- }
- }
- if (enc_found == 0) {
- printk("[%s][%d] enc_found failed!\n", __func__, __LINE__);
- return -EINVAL;
- } else {
- if (enc_context->ker_req_data_addr)
- tz_free_shared_mem(enc_context->ker_req_data_addr, TEEI_1K_SIZE);
- if (enc_context->ker_res_data_addr)
- tz_free_shared_mem(enc_context->ker_res_data_addr, TEEI_1K_SIZE);
- list_del(&enc_context->head);
- /* kfree(enc_context->meta); */
- tz_free_shared_mem(enc_context->meta, sizeof(struct teei_encode_meta) *
- (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS));
- kfree(enc_context);
- }
- return 0;
- }
- /**
- * @brief search the teei_encode and teei_session structures
- * if there is no structure, create one.
- * @param private_data Context ID
- * @param enc
- * @param penc_context
- * @param psession
- *
- * @return EINVAL: Invalid parament
- * ENOMEM: No enough memory
- * 0: success
- */
- static int teei_client_prepare_encode(void *private_data,
- struct teei_client_encode_cmd *enc,
- struct teei_encode **penc_context,
- struct teei_session **psession)
- {
- struct teei_context *temp_cont = NULL;
- struct teei_session *temp_ses = NULL;
- struct teei_encode *enc_context = NULL;
- int session_found = 0;
- int enc_found = 0;
- int retVal = 0;
- unsigned long dev_file_id = (unsigned long)private_data;
- /* search the context session with private_data */
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- list_for_each_entry(temp_ses, &temp_cont->sess_link, link) {
- if (temp_ses->sess_id == enc->session_id) {
- session_found = 1;
- break;
- }
- }
- }
- if (session_found == 1)
- break;
- }
- if (!session_found) {
- printk("[%s][%d] session (ID: %x) not found!\n", __func__, __LINE__, enc->session_id);
- return -EINVAL;
- }
- /*
- * check if the enc struct had been inited.
- */
- if (enc->encode_id != -1) {
- list_for_each_entry(enc_context, &temp_ses->encode_list, head) {
- if (enc_context->encode_id == enc->encode_id) {
- enc_found = 1;
- break;
- }
- }
- }
- /* create one command parament block */
- if (!enc_found) {
- enc_context = (struct teei_encode *)tz_malloc(sizeof(struct teei_encode), GFP_KERNEL);
- if (enc_context == NULL) {
- printk("[%s][%d] tz_malloc failed!\n", __func__, __LINE__);
- return -ENOMEM;
- }
- enc_context->meta = tz_malloc_shared_mem(sizeof(struct teei_encode_meta) *
- (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS),
- GFP_KERNEL | GFP_DMA);
- if (enc_context->meta == NULL) {
- printk("[%s][%d] tz_malloc failed!\n", __func__, __LINE__);
- kfree(enc_context);
- return -ENOMEM;
- }
- memset(enc_context->meta, 0, sizeof(struct teei_encode_meta) *
- (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS));
- enc_context->encode_id = (unsigned long)enc_context;
- enc_context->ker_req_data_addr = NULL;
- enc_context->ker_res_data_addr = NULL;
- enc_context->enc_req_offset = 0;
- enc_context->enc_res_offset = 0;
- enc_context->enc_req_pos = 0;
- enc_context->enc_res_pos = TEEI_MAX_REQ_PARAMS;
- enc_context->dec_res_pos = TEEI_MAX_REQ_PARAMS;
- enc_context->dec_offset = 0;
- list_add_tail(&enc_context->head, &temp_ses->encode_list);
- enc->encode_id = enc_context->encode_id;
- }
- /* return the enc_context & temp_ses */
- *penc_context = enc_context;
- *psession = temp_ses;
- return retVal;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_encode_uint32(void *private_data, void *argp)
- {
- struct teei_client_encode_cmd enc;
- int retVal = 0;
- struct teei_session *session = NULL;
- struct teei_encode *enc_context = NULL;
- if (copy_from_user(&enc, argp, sizeof(enc))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- retVal = teei_client_prepare_encode(private_data, &enc, &enc_context, &session);
- if (retVal != 0) {
- printk("[%s][%d] failed!\n", __func__, __LINE__);
- return retVal;
- }
- /*
- TZDebug("enc.data= %p",(void *)enc.data);
- printk("[%s][%d] enc.encode_id = %x\n", __func__, __LINE__, enc.encode_id);
- printk("[%s][%d] enc_context->encode_id = %x\n", __func__, __LINE__, enc_context->encode_id);
- */
- if (enc.param_type == TEEIC_PARAM_IN) {
- if (enc_context->ker_req_data_addr == NULL) {
- enc_context->ker_req_data_addr = tz_malloc_shared_mem(TEEI_1K_SIZE, GFP_KERNEL | GFP_DMA);
- if (enc_context->ker_req_data_addr == NULL) {
- printk("[%s][%d] tz_malloc failed!\n", __func__, __LINE__);
- retVal = -ENOMEM;
- goto ret_encode_u32;
- }
- }
- if ((enc_context->enc_req_offset + sizeof(u32) <= TEEI_1K_SIZE) &&
- (enc_context->enc_req_pos < TEEI_MAX_REQ_PARAMS)) {
- u64 addr = enc.data;
- void __user *pt = compat_ptr((unsigned int *)addr);
- u32 value = 0;
- copy_from_user(&value, pt, 4);
- *(u32 *)((char *)enc_context->ker_req_data_addr + enc_context->enc_req_offset) = value;
- TZDebug("value %x", value);
- enc_context->enc_req_offset += sizeof(u32);
- enc_context->meta[enc_context->enc_req_pos].type = TEEI_ENC_UINT32;
- enc_context->meta[enc_context->enc_req_pos].len = sizeof(u32);
- enc_context->meta[enc_context->enc_req_pos].value_flag = enc.value_flag;
- enc_context->meta[enc_context->enc_req_pos].param_pos = enc.param_pos;
- enc_context->meta[enc_context->enc_req_pos].param_pos_type = enc.param_pos_type;
- enc_context->enc_req_pos++;
- } else {
- tz_free_shared_mem(enc_context->ker_req_data_addr, TEEI_1K_SIZE);
- retVal = -ENOMEM;
- goto ret_encode_u32;
- }
- } else if (enc.param_type == TEEIC_PARAM_OUT) {
- if (!enc_context->ker_res_data_addr) {
- enc_context->ker_res_data_addr = tz_malloc_shared_mem(TEEI_1K_SIZE, GFP_KERNEL | GFP_DMA);
- if (!enc_context->ker_res_data_addr) {
- printk("[%s][%d] tz_malloc failed\n", __func__, __LINE__);
- retVal = -ENOMEM;
- goto ret_encode_u32;
- }
- }
- if ((enc_context->enc_res_offset + sizeof(u32) <= TEEI_1K_SIZE) &&
- (enc_context->enc_res_pos < (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS))) {
- if (enc.data != NULL) {
- u64 addr = enc.data;
- void __user *pt = compat_ptr((unsigned int *)addr);
- /*
- u32 value = 0;
- copy_from_user(&value, pt, 4);
- TZDebug("value %x", value);
- */
- enc_context->meta[enc_context->enc_res_pos].usr_addr = pt;
- } else {
- enc_context->meta[enc_context->enc_res_pos].usr_addr = 0;
- }
- enc_context->enc_res_offset += sizeof(u32);
- enc_context->meta[enc_context->enc_res_pos].type = TEEI_ENC_UINT32;
- enc_context->meta[enc_context->enc_res_pos].len = sizeof(u32);
- enc_context->meta[enc_context->enc_res_pos].value_flag = enc.value_flag;
- enc_context->meta[enc_context->enc_res_pos].param_pos = enc.param_pos;
- enc_context->meta[enc_context->enc_res_pos].param_pos_type = enc.param_pos_type;
- enc_context->enc_res_pos++;
- } else {
- /* kfree(enc_context->ker_res_data_addr); */
- tz_free_shared_mem(enc_context->ker_res_data_addr, TEEI_1K_SIZE);
- retVal = -ENOMEM;
- goto ret_encode_u32;
- }
- }
- ret_encode_u32:
- if (copy_to_user(argp, &enc, sizeof(enc))) {
- TERR("copy from user failed ");
- retVal = -EFAULT;
- }
- return retVal;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_encode_array(void *private_data, void *argp)
- {
- struct teei_client_encode_cmd enc;
- int retVal = 0;
- struct teei_encode *enc_context = NULL;
- struct teei_session *session = NULL;
- if (copy_from_user(&enc, argp, sizeof(enc))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- retVal = teei_client_prepare_encode(private_data, &enc, &enc_context, &session);
- if (retVal)
- goto return_func;
- if (enc.param_type == TEEIC_PARAM_IN) {
- if (NULL == enc_context->ker_req_data_addr) {
- /* printk("[%s][%d] allocate req data data.\n", __func__, __LINE__); */
- enc_context->ker_req_data_addr = tz_malloc_shared_mem(TEEI_1K_SIZE, GFP_KERNEL | GFP_DMA);
- if (!enc_context->ker_req_data_addr) {
- printk("[%s][%d] tz_malloc failed!\n", __func__, __LINE__);
- retVal = -ENOMEM;
- goto ret_encode_array;
- }
- }
- if ((enc_context->enc_req_offset + enc.len <= TEEI_1K_SIZE) &&
- (enc_context->enc_req_pos < TEEI_MAX_REQ_PARAMS)) {
- if (copy_from_user(
- (char *)enc_context->ker_req_data_addr + enc_context->enc_req_offset,
- enc.data , enc.len)) {
- printk("[%s][%d] copy from user failed.\n", __func__, __LINE__);
- retVal = -EFAULT;
- goto ret_encode_array;
- }
- enc_context->enc_req_offset += enc.len;
- enc_context->meta[enc_context->enc_req_pos].type = TEEI_ENC_ARRAY;
- enc_context->meta[enc_context->enc_req_pos].len = enc.len;
- enc_context->meta[enc_context->enc_req_pos].param_pos = enc.param_pos;
- enc_context->meta[enc_context->enc_req_pos].param_pos_type = enc.param_pos_type;
- enc_context->enc_req_pos++;
- } else {
- /* kfree(enc_context->ker_req_data_addr); */
- tz_free_shared_mem(enc_context->ker_req_data_addr, TEEI_1K_SIZE);
- retVal = -ENOMEM;
- goto ret_encode_array;
- }
- } else if (enc.param_type == TEEIC_PARAM_OUT) {
- if (NULL == enc_context->ker_res_data_addr) {
- enc_context->ker_res_data_addr = tz_malloc_shared_mem(TEEI_1K_SIZE, GFP_KERNEL | GFP_DMA);
- if (NULL == enc_context->ker_res_data_addr) {
- printk("[%s][%d] tz_malloc failed!\n", __func__, __LINE__);
- retVal = -ENOMEM;
- goto ret_encode_array;
- }
- }
- if ((enc_context->enc_res_offset + enc.len <= TEEI_1K_SIZE) &&
- (enc_context->enc_res_pos <
- (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS))) {
- if (enc.data != NULL) {
- enc_context->meta[enc_context->enc_res_pos].usr_addr
- = (unsigned long)enc.data;
- } else {
- enc_context->meta[enc_context->enc_res_pos].usr_addr = 0;
- }
- enc_context->enc_res_offset += enc.len;
- enc_context->meta[enc_context->enc_res_pos].type = TEEI_ENC_ARRAY;
- enc_context->meta[enc_context->enc_res_pos].len = enc.len;
- enc_context->meta[enc_context->enc_res_pos].param_pos = enc.param_pos;
- enc_context->meta[enc_context->enc_res_pos].param_pos_type = enc.param_pos_type;
- enc_context->enc_res_pos++;
- } else {
- /* kfree(enc_context->ker_res_data_addr); */
- tz_free_shared_mem(enc_context->ker_req_data_addr, TEEI_1K_SIZE);
- retVal = -ENOMEM;
- goto ret_encode_array;
- }
- }
- ret_encode_array:
- if (copy_to_user(argp, &enc, sizeof(enc))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- return_func:
- TDEBUG("[%s][%d] teei_client_encode_array end!\n", __func__, __LINE__);
- return retVal;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_encode_mem_ref(void *private_data, void *argp)
- {
- struct teei_client_encode_cmd enc;
- int retVal = 0;
- int shared_mem_found = 0;
- struct teei_encode *enc_context = NULL;
- struct teei_session *session = NULL;
- struct teei_shared_mem *temp_shared_mem = NULL;
- if (copy_from_user(&enc, argp, sizeof(enc))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- retVal = teei_client_prepare_encode(private_data, &enc, &enc_context, &session);
- if (retVal != 0)
- goto return_func;
- list_for_each_entry(temp_shared_mem, &session->shared_mem_list, s_head) {
- u64 addr = enc.data;
- if (temp_shared_mem && temp_shared_mem->index == (u32 *)addr) {
- shared_mem_found = 1;
- break;
- }
- }
- if (shared_mem_found == 0) {
- struct teei_context *temp_cont = NULL;
- list_for_each_entry(temp_cont,
- &teei_contexts_head.context_list,
- link) {
- if (temp_cont->cont_id == (unsigned long)private_data) {
- list_for_each_entry(temp_shared_mem,
- &temp_cont->shared_mem_list,
- head) {
- if (temp_shared_mem->index == (u32)enc.data) {
- shared_mem_found = 1;
- break;
- }
- }
- break;
- }
- if (shared_mem_found == 1)
- break;
- }
- }
- if (!shared_mem_found) {
- retVal = -EINVAL;
- goto return_func;
- }
- if (enc.param_type == TEEIC_PARAM_IN) {
- if (NULL == enc_context->ker_req_data_addr) {
- enc_context->ker_req_data_addr = tz_malloc_shared_mem(TEEI_1K_SIZE, GFP_KERNEL | GFP_DMA);
- if (NULL == enc_context->ker_req_data_addr) {
- printk("[%s][%d] tz_malloc failed!\n", __func__, __LINE__);
- retVal = -ENOMEM;
- goto ret_encode_array;
- }
- }
- if ((enc_context->enc_req_offset + sizeof(u32) <= TEEI_1K_SIZE) &&
- (enc_context->enc_req_pos < TEEI_MAX_REQ_PARAMS)) {
- *(u32 *)((char *)enc_context->ker_req_data_addr + enc_context->enc_req_offset)
- = virt_to_phys((char *)temp_shared_mem->k_addr+enc.offset);
- Flush_Dcache_By_Area((unsigned long)(temp_shared_mem->k_addr+enc.offset),
- (unsigned long)temp_shared_mem->k_addr+enc.offset+enc.len);
- enc_context->enc_req_offset += sizeof(u32);
- enc_context->meta[enc_context->enc_req_pos].usr_addr
- = (unsigned long)((char *)temp_shared_mem->u_addr + enc.offset);
- enc_context->meta[enc_context->enc_req_pos].type = TEEI_MEM_REF;
- enc_context->meta[enc_context->enc_req_pos].len = enc.len;
- enc_context->meta[enc_context->enc_req_pos].param_pos = enc.param_pos;
- enc_context->meta[enc_context->enc_req_pos].param_pos_type = enc.param_pos_type;
- enc_context->enc_req_pos++;
- } else {
- /* kfree(enc_context->ker_req_data_addr); */
- tz_free_shared_mem(enc_context->ker_req_data_addr, TEEI_1K_SIZE);
- retVal = -ENOMEM;
- goto ret_encode_array;
- }
- } else if (enc.param_type == TEEIC_PARAM_OUT) {
- if (!enc_context->ker_res_data_addr) {
- enc_context->ker_res_data_addr = tz_malloc_shared_mem(TEEI_1K_SIZE, GFP_KERNEL | GFP_DMA);
- if (!enc_context->ker_res_data_addr) {
- printk("[%s][%d] tz_malloc failed!\n", __func__, __LINE__);
- retVal = -ENOMEM;
- goto ret_encode_array;
- }
- }
- if ((enc_context->enc_res_offset + sizeof(u32) <= TEEI_1K_SIZE) &&
- (enc_context->enc_res_pos < (TEEI_MAX_RES_PARAMS + TEEI_MAX_REQ_PARAMS))) {
- *(u32 *)((char *)enc_context->ker_res_data_addr +
- enc_context->enc_res_offset)
- = virt_to_phys((char *)temp_shared_mem->k_addr + enc.offset);
- enc_context->enc_res_offset += sizeof(u32);
- enc_context->meta[enc_context->enc_res_pos].usr_addr
- = (unsigned long)((char *)temp_shared_mem->u_addr + enc.offset);
- enc_context->meta[enc_context->enc_res_pos].type
- = TEEI_MEM_REF;
- enc_context->meta[enc_context->enc_res_pos].len = enc.len;
- enc_context->meta[enc_context->enc_res_pos].param_pos = enc.param_pos;
- enc_context->meta[enc_context->enc_res_pos].param_pos_type = enc.param_pos_type;
- enc_context->enc_res_pos++;
- } else {
- /* kfree(enc_context->ker_res_data_addr); */
- tz_free_shared_mem(enc_context->ker_res_data_addr, TEEI_1K_SIZE);
- retVal = -ENOMEM;
- goto ret_encode_array;
- }
- }
- ret_encode_array:
- if (copy_to_user(argp, &enc, sizeof(enc))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- return_func:
- /* printk("[%s][%d] teei_client_encode_mem_ref end.\n", __func__, __LINE__); */
- return retVal;
- }
- static int print_context(void)
- {
- struct teei_context *temp_cont = NULL;
- struct teei_session *temp_sess = NULL;
- struct teei_encode *dec_context = NULL;
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- printk("[%s][%d] context id [%lx]\n", __func__, __LINE__, temp_cont->cont_id);
- list_for_each_entry(temp_sess, &temp_cont->sess_link, link) {
- printk("[%s][%d] session id [%x]\n", __func__, __LINE__, temp_sess->sess_id);
- /*
- list_for_each_entry(dec_context, &temp_sess->encode_list, head) {
- printk("[%s][%d] encode_id [%x]\n", __func__, __LINE__, dec_context->encode_id);
- }
- */
- }
- }
- return 0;
- }
- /**
- * @brief
- *
- * @param dec
- * @param pdec_context
- *
- * @return
- */
- static int teei_client_prepare_decode(void *private_data,
- struct teei_client_encode_cmd *dec,
- struct teei_encode **pdec_context)
- {
- struct teei_context *temp_cont = NULL;
- struct teei_session *temp_ses = NULL;
- struct teei_encode *dec_context = NULL;
- int session_found = 0;
- int enc_found = 0;
- unsigned long dev_file_id = (unsigned long)private_data;
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- list_for_each_entry(temp_ses, &temp_cont->sess_link, link) {
- if (temp_ses->sess_id == dec->session_id) {
- session_found = 1;
- break;
- }
- }
- break;
- }
- }
- if (0 == session_found) {
- printk("[%s][%d] session not found!\n", __func__, __LINE__);
- return -EINVAL;
- }
- if (dec->encode_id != -1) {
- list_for_each_entry(dec_context, &temp_ses->encode_list, head) {
- if (dec_context->encode_id == dec->encode_id) {
- enc_found = 1;
- break;
- }
- }
- }
- /* print_context(); */
- if (0 == enc_found) {
- printk("[%s][%d] encode[%x] not found!\n", __func__, __LINE__, dec->encode_id);
- return -EINVAL;
- }
- *pdec_context = dec_context;
- return 0;
- }
- /**
- * @brief Decode the uint32 result
- *
- * @param argp
- *
- * @return EFAULT: fail to copy data from user space OR to user space.
- * 0: success
- */
- static int teei_client_decode_uint32(void *private_data, void *argp)
- {
- struct teei_client_encode_cmd dec;
- int retVal = 0;
- struct teei_encode *dec_context = NULL;
- if (copy_from_user(&dec, argp, sizeof(dec))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- retVal = teei_client_prepare_decode(private_data, &dec, &dec_context);
- if (retVal != 0) {
- printk("[%s][%d] teei_client_prepare_decode failed!\n", __func__, __LINE__);
- goto return_func;
- }
- if ((dec_context->dec_res_pos <= dec_context->enc_res_pos) &&
- (dec_context->meta[dec_context->dec_res_pos].type == TEEI_ENC_UINT32)) {
- if (dec_context->meta[dec_context->dec_res_pos].usr_addr) {
- dec.data = (void *)dec_context->meta[dec_context->dec_res_pos].usr_addr;
- TZDebug("data %x", dec.data);
- }
- u32 value = 0;
- u64 addr = dec.data;
- void __user *pt = compat_ptr((unsigned int *)addr);
- /* *(u32 *)dec.data = *((u32 *)((char *)dec_context->ker_res_data_addr + dec_context->dec_offset)); */
- value = *((u32 *)((char *)dec_context->ker_res_data_addr + dec_context->dec_offset));
- copy_to_user(pt, &value, 4);
- dec_context->dec_offset += sizeof(u32);
- dec_context->dec_res_pos++;
- }
- if (copy_to_user(argp, &dec, sizeof(dec))) {
- printk("[%s][%d] copy to user failed.\n", __func__, __LINE__);
- return -EFAULT;
- }
- return_func:
- return retVal;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_decode_array_space(void *private_data, void *argp)
- {
- struct teei_client_encode_cmd dec;
- int retVal = 0;
- struct teei_encode *dec_context = NULL;
- if (copy_from_user(&dec, argp, sizeof(dec))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- retVal = teei_client_prepare_decode(private_data, &dec, &dec_context);
- if (retVal != 0)
- goto return_func;
- if ((dec_context->dec_res_pos <= dec_context->enc_res_pos) &&
- (dec_context->meta[dec_context->dec_res_pos].type
- == TEEI_ENC_ARRAY)) {
- if (dec_context->meta[dec_context->dec_res_pos].len >=
- dec_context->meta[dec_context->dec_res_pos].ret_len) {
- if (dec_context->meta[dec_context->dec_res_pos].usr_addr)
- dec.data = (void *)dec_context->meta[dec_context->dec_res_pos].usr_addr;
- if (copy_to_user(dec.data, (char *)dec_context->ker_res_data_addr + dec_context->dec_offset,
- dec_context->meta[dec_context->dec_res_pos].ret_len)) {
- printk("[%s][%d] copy from user failed while copying array!\n", __func__, __LINE__);
- retVal = -EFAULT;
- goto return_func;
- }
- } else {
- printk("[%s][%d] buffer length is small. Length required %x and supplied length %x,pos %x ",
- __func__, __LINE__,
- dec_context->meta[dec_context->dec_res_pos].ret_len,
- dec_context->meta[dec_context->dec_res_pos].len,
- dec_context->dec_res_pos);
- retVal = -EFAULT;
- goto return_func;
- }
- dec.len = dec_context->meta[dec_context->dec_res_pos].ret_len;
- dec_context->dec_offset += dec_context->meta[dec_context->dec_res_pos].len;
- dec_context->dec_res_pos++;
- } else if ((dec_context->dec_res_pos <= dec_context->enc_res_pos) &&
- (dec_context->meta[dec_context->dec_res_pos].type == TEEI_MEM_REF)) {
- if (dec_context->meta[dec_context->dec_res_pos].len >=
- dec_context->meta[dec_context->dec_res_pos].ret_len) {
- dec.data = (void *)dec_context->meta[dec_context->dec_res_pos].usr_addr;
- unsigned long pmem = *(u32 *)((char *)dec_context->ker_res_data_addr + dec_context->dec_offset);
- char *mem = NULL;
- unsigned long addr = (unsigned long)phys_to_virt(pmem);
- mem = (char *)addr;
- Invalidate_Dcache_By_Area((unsigned long)mem,
- (unsigned long)mem+dec_context->meta[dec_context->dec_res_pos].ret_len + 1);
- } else {
- printk("[%s][%d] buffer length is small. Length required %x and supplied length %x",
- __func__, __LINE__,
- dec_context->meta[dec_context->dec_res_pos].ret_len,
- dec_context->meta[dec_context->dec_res_pos].len);
- retVal = -EFAULT;
- goto return_func;
- }
- dec.len = dec_context->meta[dec_context->dec_res_pos].ret_len;
- dec_context->dec_offset += sizeof(u32);
- dec_context->dec_res_pos++;
- }
- else {
- printk("[%s][%d] invalid data type or decoder at wrong position!\n", __func__, __LINE__);
- retVal = -EINVAL;
- goto return_func;
- }
- if (copy_to_user(argp, &dec, sizeof(dec))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- retVal = -EFAULT;
- goto return_func;
- }
- return_func:
- TDEBUG("[%s][%d] teei_client_decode_array_space end.\n", __func__, __LINE__);
- return retVal;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_get_decode_type(void *private_data, void *argp)
- {
- struct teei_client_encode_cmd dec;
- int retVal = 0;
- struct teei_encode *dec_context = NULL;
- if (copy_from_user(&dec, argp, sizeof(dec))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- retVal = teei_client_prepare_decode(private_data, &dec, &dec_context);
- if (retVal != 0)
- return retVal;
- if (dec_context->dec_res_pos <= dec_context->enc_res_pos)
- dec.data = (unsigned long)dec_context->meta[dec_context->dec_res_pos].type;
- else
- return -EINVAL;
- if (copy_to_user(argp, &dec, sizeof(dec))) {
- printk("[%s][%d] copy to user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- return retVal;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_shared_mem_alloc(void *private_data, void *argp)
- {
- #if 0
- struct teei_shared_mem *temp_shared_mem = NULL;
- struct teei_session_shared_mem_info mem_info;
- struct teei_context *temp_cont = NULL;
- struct teei_session *temp_ses = NULL;
- int session_found = 0;
- unsigned long dev_file_id = (unsigned long)private_data;
- if (copy_from_user(&mem_info, argp, sizeof(mem_info))) {
- printk("[%s][%d] copy from user failed!\n", __func__, __LINE__);
- return -EFAULT;
- }
- /*
- printk("[%s][%d] service id 0x%lx session id 0x%lx user mem addr 0x%p.\n",
- __func__, __LINE__,
- mem_info.service_id,
- mem_info.session_id,
- mem_info.user_mem_addr);
- */
- list_for_each_entry(temp_cont,
- &teei_contexts_head.context_list,
- link) {
- if (temp_cont->cont_id == dev_file_id) {
- list_for_each_entry(temp_ses, &temp_cont->sess_link, link) {
- if (temp_ses->sess_id == mem_info.session_id) {
- session_found = 1;
- break;
- }
- }
- break;
- }
- }
- if (session_found == 0) {
- printk("[%s][%d] session not found!\n", __func__, __LINE__);
- return -EINVAL;
- }
- list_for_each_entry(temp_shared_mem, &temp_cont->shared_mem_list, head) {
- if (temp_shared_mem->index == (void *)mem_info.user_mem_addr) {
- list_del(&temp_shared_mem->head);
- temp_cont->shared_mem_cnt--;
- list_add_tail(&temp_shared_mem->s_head, &temp_ses->shared_mem_list);
- break;
- }
- }
- #endif
- return 0;
- }
- /**
- * @brief
- *
- * @param argp
- *
- * @return
- */
- static int teei_client_shared_mem_free(void *private_data, void *argp)
- {
- struct teei_shared_mem *temp_shared_mem = NULL;
- struct teei_session_shared_mem_info mem_info;
- struct teei_context *temp_cont = NULL;
- struct teei_session *temp_ses = NULL;
- struct teei_shared_mem *temp_pos = NULL;
- int session_found = 0;
- unsigned long dev_file_id = (unsigned long)private_data;
- if (copy_from_user(&mem_info, argp, sizeof(mem_info))) {
- printk("[%s][%d] copy from user failed.\n", __func__, __LINE__);
- return -EFAULT;
- }
- TZDebug("session id 0x%x user mem addr %x ",
- mem_info.session_id,
- mem_info.user_mem_addr);
- list_for_each_entry(temp_cont,
- &teei_contexts_head.context_list,
- link) {
- if (temp_cont->cont_id == dev_file_id) {
- TDEBUG("found file id");
- list_for_each_entry_safe(temp_shared_mem,
- temp_pos,
- &temp_cont->shared_mem_list,
- head) {
- if (temp_shared_mem && temp_shared_mem->u_addr == mem_info.user_mem_addr) {
- list_del(&temp_shared_mem->head);
- if (temp_shared_mem->k_addr)
- free_pages((u64)temp_shared_mem->k_addr,
- get_order(ROUND_UP(temp_shared_mem->len, SZ_4K)));
- kfree(temp_shared_mem);
- }
- }
- }
- }
- #if 0
- list_for_each_entry(temp_cont, &teei_contexts_head.context_list, link) {
- if (temp_cont->cont_id == dev_file_id) {
- list_for_each_entry(temp_ses, &temp_cont->sess_link, link) {
- TZDebug("list:session id %x", temp_ses->sess_id);
- if (temp_ses->sess_id == mem_info.session_id) {
- session_found = 1;
- break;
- }
- }
- break;
- }
- }
- if (session_found == 0) {
- printk("[%s][%d] session not found!\n", __func__, __LINE__);
- return -EINVAL;
- }
- list_for_each_entry(temp_shared_mem, &temp_ses->shared_mem_list, s_head) {
- if (temp_shared_mem && temp_shared_mem->index == (void *)mem_info.user_mem_addr) {
- list_del(&temp_shared_mem->s_head);
- if (temp_shared_mem->k_addr)
- free_pages((unsigned long)temp_shared_mem->k_addr,
- get_order(ROUND_UP(temp_shared_mem->len, SZ_4K)));
- kfree(temp_shared_mem);
- break;
- }
- }
- #endif
- return 0;
- }
- /**
- * @brief
- *
- * @param file
- * @param cmd
- * @param arg
- * @return
- */
- static long teei_client_ioctl(struct file *file, unsigned cmd, unsigned long arg)
- {
- int retVal = 0;
- void *argp = (void __user *) arg;
- if (teei_config_flag == 0) {
- printk("Error: soter is NOT ready, Can not support IOCTL!\n");
- return -ECANCELED;
- }
- down(&api_lock);
- mutex_lock(&pm_mutex);
- switch (cmd) {
- case TEEI_CLIENT_IOCTL_INITCONTEXT_REQ:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_INITCONTEXT beginning .....\n", __func__, __LINE__);
- retVal = teei_client_context_init(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed init context %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_INITCONTEXT end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_CLOSECONTEXT_REQ:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_CLOSECONTEXT beginning .....\n", __func__, __LINE__);
- retVal = teei_client_context_close(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed close context: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_CLOSECONTEXT end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_SES_INIT_REQ:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SES_INIT beginning .....\n", __func__, __LINE__);
- retVal = teei_client_session_init(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed session init: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SES_INIT end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_SES_OPEN_REQ:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SES_OPEN beginning .....\n", __func__, __LINE__);
- retVal = teei_client_session_open(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed session open: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SES_OPEN end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_SES_CLOSE_REQ:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SES_CLOSE beginning .....\n", __func__, __LINE__);
- retVal = teei_client_session_close(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed session close: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SES_CLOSE end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_OPERATION_RELEASE:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_OPERATION_RELEASE beginning .....\n", __func__, __LINE__);
- retVal = teei_client_operation_release(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed operation release: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_OPERATION_RELEASE end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_SEND_CMD_REQ:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SEND_CMD beginning .....\n", __func__, __LINE__);
- retVal = teei_client_send_cmd(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed send cmd: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SEND_CMD end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_GET_DECODE_TYPE:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_GET_DECODE beginning .....\n", __func__, __LINE__);
- retVal = teei_client_get_decode_type(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed decode cmd: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_GET_DECODE end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_ENC_UINT32:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_ENC_UINT32 beginning .....\n", __func__, __LINE__);
- retVal = teei_client_encode_uint32(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed teei_client_encode_cmd: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_ENC_UINT32 end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_DEC_UINT32:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_DEC_UINT32 beginning .....\n", __func__, __LINE__);
- retVal = teei_client_decode_uint32(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed teei_client_decode_cmd: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_DEC_UINT32 end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_ENC_ARRAY:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_ENC_ARRAY beginning .....\n", __func__, __LINE__);
- retVal = teei_client_encode_array(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed teei_client_encode_cmd: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_ENC_ARRAY end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_DEC_ARRAY_SPACE:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_DEC_ARRAY_SPACE beginning .....\n", __func__, __LINE__);
- retVal = teei_client_decode_array_space(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed teei_client_decode_cmd: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_DEC_ARRAY_SPACE end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_ENC_MEM_REF:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_DEC_MEM_REF beginning .....\n", __func__, __LINE__);
- retVal = teei_client_encode_mem_ref(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed teei_client_encode_cmd: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_DEC_MEM_REF end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_ENC_ARRAY_SPACE:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_ENC_ARRAY_SPACE beginning .....\n", __func__, __LINE__);
- retVal = teei_client_encode_mem_ref(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed teei_client_encode_cmd: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_ENC_ARRAY_SPACE end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_SHR_MEM_ALLOCATE_REQ:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SHR_MEM_ALLOCATE beginning .....\n", __func__, __LINE__);
- retVal = teei_client_shared_mem_alloc(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed teei_client_shared_mem_alloc: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SHR_MEM_ALLOCATE end .....\n", __func__, __LINE__);
- break;
- case TEEI_CLIENT_IOCTL_SHR_MEM_FREE_REQ:
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SHR_MEM_FREE beginning .....\n", __func__, __LINE__);
- retVal = teei_client_shared_mem_free(file->private_data, argp);
- if (retVal != 0)
- printk("[%s][%d] failed teei_client_shared_mem_free: %x.\n", __func__, __LINE__, retVal);
- printk("[%s][%d] TEEI_CLIENT_IOCTL_SHR_MEM_FREE end .....\n", __func__, __LINE__);
- break;
- case TEEI_GET_TEEI_CONFIG_STAT:
- printk("[%s][%d] TEEI_GET_TEEI_CONFIG_STAT beginning .....\n", __func__, __LINE__);
- retVal = teei_config_flag;
- printk("[%s][%d] TEEI_GET_TEEI_CONFIG_STAT end .....\n", __func__, __LINE__);
- break;
- default:
- printk("[%s][%d] command not found!\n", __func__, __LINE__);
- retVal = -EINVAL;
- }
- mutex_unlock(&pm_mutex);
- up(&api_lock);
- return retVal;
- }
- /**
- * @brief The open operation of /dev/teei_client device node.
- *
- * @param inode
- * @param file
- *
- * @return ENOMEM: no enough memory in the linux kernel
- * 0: on success
- */
- static int teei_client_open(struct inode *inode, struct file *file)
- {
- struct teei_context *new_context = NULL;
- device_file_cnt++;
- file->private_data = (void *)device_file_cnt;
- new_context = (struct teei_context *)tz_malloc(sizeof(struct teei_context), GFP_KERNEL);
- if (new_context == NULL) {
- printk("tz_malloc failed for new dev file allocation!\n");
- return -ENOMEM;
- }
- new_context->cont_id = device_file_cnt;
- INIT_LIST_HEAD(&(new_context->sess_link));
- INIT_LIST_HEAD(&(new_context->link));
- new_context->shared_mem_cnt = 0;
- INIT_LIST_HEAD(&(new_context->shared_mem_list));
- sema_init(&(new_context->cont_lock), 0);
- down_write(&(teei_contexts_head.teei_contexts_sem));
- list_add(&(new_context->link), &(teei_contexts_head.context_list));
- teei_contexts_head.dev_file_cnt++;
- up_write(&(teei_contexts_head.teei_contexts_sem));
- return 0;
- }
- /**
- * @brief The release operation of /dev/teei_client device node.
- *
- * @param inode: device inode structure
- * @param file: struct file
- *
- * @return 0: on success
- */
- static int teei_client_release(struct inode *inode, struct file *file)
- {
- int retVal = 0;
- retVal = teei_client_service_exit(file->private_data);
- return retVal;
- }
- #endif
- static irqreturn_t mt_deint_soft_revert_isr(unsigned irq, struct irq_desc *desc)
- {
- irq_set_irq_type(irq, IRQF_TRIGGER_RISING);
- return IRQ_HANDLED;
- }
- static void eint_gic_attach(void)
- {
- int ret = 0;
- ret = mt_eint_set_deint(6, 189);
- if (ret == 0)
- printk("mt_eint_set_deint done\n");
- else {
- printk("mt_eint_set_deint fail\n");
- return;
- }
- mt_irq_set_polarity(189, IRQF_TRIGGER_FALLING); /*IRQF_TRIGGER_RISING*/
- /*
- ret = request_irq(189, (irq_handler_t)mt_deint_soft_revert_isr,
- IRQF_TRIGGER_RISING, "EINT-AUTOUNMASK", NULL);
- if (ret > 0) {
- printk(KERN_ERR "EINT IRQ LINE NOT AVAILABLE!!\n");
- return;
- }
- printk("EINT %d request_irq done\n",eint_num);
- irq_set_irq_type(189, IRQF_TRIGGER_RISING);
- printk("trigger EINT %d done\n",eint_num);
- printk("MASK 0x%x\n",mt_eint_get_mask(6));
- mt_eint_clr_deint(eint_num);
- */
- }
- /**
- * @brief
- *
- * @return
- */
- static void teei_client_smc_init(void)
- {
- #if 0
- neu_disable_touch_irq();
- eint_gic_attach();
- enable_clock(25, "i2c");
- n_switch_to_t_os_stage2();
- switch_enable_flag = 1;
- mt_eint_clr_deint(6);
- neu_enable_touch_irq();
- #endif
- }
- #if 0
- void NQ_init(unsigned long NQ_buff)
- {
- memset((char *)NQ_buff, 0, NQ_BUFF_SIZE);
- }
- static __always_inline unsigned int get_end_index(struct NQ_head *nq_head)
- {
- if (nq_head->end_index == BLOCK_MAX_COUNT)
- return 1;
- else
- return nq_head->end_index + 1;
- }
- #endif
- static irqreturn_t nt_sched_irq_handler(void)
- {
- int cpu_id = raw_smp_processor_id();
- if (boot_soter_flag == START_STATUS) {
- forward_call_flag = GLSCH_FOR_SOTER;
- up(&smc_lock);
- return IRQ_HANDLED;
- } else {
- up(&smc_lock);
- return IRQ_HANDLED;
- }
- }
- int register_sched_irq_handler(void)
- {
- int retVal = 0;
- #ifdef CONFIG_OF
- int irq_num = 0;
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "microtrust,utos");
- irq_num = irq_of_parse_and_map(node, 5);
- retVal = request_irq(irq_num, nt_sched_irq_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("[CONFIG_OF] [%s] ERROR for request_irq %d error code : %d.\n", __func__, irq_num, retVal);
- else
- printk("[CONFIG_OF] [%s] request irq [ %d ] OK.\n", __func__, irq_num);
- #else
- /* register 284 IRQ */
- retVal = request_irq(SCHED_IRQ, nt_sched_irq_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("ERROR for request_irq %d error code : %d.\n", SCHED_IRQ, retVal);
- else
- printk("request irq [ %d ] OK.\n", SCHED_IRQ);
- #endif
- return 0;
- }
- static irqreturn_t nt_soter_irq_handler(void)
- {
- int cpu_id = raw_smp_processor_id();
- irq_call_flag = GLSCH_HIGH;
- up(&smc_lock);
- if (teei_config_flag == 1) {
- complete(&global_down_lock);
- }
- return IRQ_HANDLED;
- }
- int register_soter_irq_handler(void)
- {
- int retVal = 0;
- #ifdef CONFIG_OF
- int irq_num = 0;
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "microtrust,utos");
- irq_num = irq_of_parse_and_map(node, 6);
- retVal = request_irq(irq_num, nt_soter_irq_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("[CONFIG_OF] [%s] ERROR for request_irq %d error code : %d.\n", __func__, irq_num, retVal);
- else
- printk("[CONFIG_OF] [%s] request irq [ %d ] OK.\n", __func__, irq_num);
- #else
- /* register 285 IRQ */
- retVal = request_irq(SOTER_IRQ, nt_soter_irq_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("ERROR for request_irq %d error code : %d.\n", SOTER_IRQ, retVal);
- else
- printk("request irq [ %d ] OK.\n", SOTER_IRQ);
- #endif
- return 0;
- }
- static irqreturn_t nt_error_irq_handler(void)
- {
- printk("secure system ERROR !\n");
- soter_error_flag = 1;
- up(&(boot_sema));
- up(&smc_lock);
- return IRQ_HANDLED;
- }
- int register_error_irq_handler(void)
- {
- int retVal = 0;
- #ifdef CONFIG_OF
- int irq_num = 0;
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "microtrust,utos");
- irq_num = irq_of_parse_and_map(node, 0);
- retVal = request_irq(irq_num, nt_error_irq_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("[CONFIG_OF] [%s] ERROR for request_irq %d error code : %d.\n", __func__, irq_num, retVal);
- else
- printk("[CONFIG_OF] [%s] request irq [ %d ] OK.\n", __func__, irq_num);
- #else
- /* register 276 IRQ */
- retVal = request_irq(SOTER_ERROR_IRQ, nt_error_irq_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("ERROR for request_irq %d error code : %d.\n", SOTER_ERROR_IRQ, retVal);
- else
- printk("request irq [ %d ] OK.\n", SOTER_ERROR_IRQ);
- #endif
- return 0;
- }
- static irqreturn_t nt_fp_ack_handler(void)
- {
- fp_call_flag = GLSCH_NONE;
- up(&boot_sema);
- up(&smc_lock);
- return IRQ_HANDLED;
- }
- int register_fp_ack_handler(void)
- {
- int retVal = 0;
- #ifdef CONFIG_OF
- int irq_num = 0;
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "microtrust,utos");
- irq_num = irq_of_parse_and_map(node, 7);
- retVal = request_irq(irq_num, nt_fp_ack_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("[CONFIG_OF] [%s] ERROR for request_irq %d error code : %d.\n", __func__, irq_num, retVal);
- else
- printk("[CONFIG_OF] [%s] request irq [ %d ] OK.\n", __func__, irq_num);
- #else
- /* register 287 IRQ */
- retVal = request_irq(FP_ACK_IRQ, nt_fp_ack_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("ERROR for request_irq %d error code : %d.\n", FP_ACK_IRQ, retVal);
- else
- printk("request irq [ %d ] OK.\n", FP_ACK_IRQ);
- #endif
- return 0;
- }
- int get_bdrv_id(void)
- {
- int driver_id = 0;
- driver_id = *((int *)bdrv_message_buff);
- return driver_id;
- }
- static irqreturn_t nt_bdrv_handler(void)
- {
- int bdrv_id = 0;
- int cpu_id = raw_smp_processor_id();
- bdrv_id = get_bdrv_id();
- #if 0
- if (bdrv_id == TEEI_VFS_NUM) {
- teei_vfs_flag = 1;
- }
- #endif
- teei_vfs_flag = 1;
- add_bdrv_queue(bdrv_id);
- up(&smc_lock);
- return IRQ_HANDLED;
- }
- int register_bdrv_handler(void)
- {
- int retVal = 0;
- #ifdef CONFIG_OF
- int irq_num = 0;
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "microtrust,utos");
- irq_num = irq_of_parse_and_map(node, 2);
- retVal = request_irq(irq_num, nt_bdrv_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("[CONFIG_OF] [%s] ERROR for request_irq %d error code : %d.\n", __func__, irq_num, retVal);
- else
- printk("[CONFIG_OF] [%s] request irq [ %d ] OK.\n", __func__, irq_num);
- #else
- /* register 278 IRQ */
- retVal = request_irq(BDRV_IRQ, nt_bdrv_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("ERROR for request_irq %d error code : %d.\n", BDRV_IRQ, retVal);
- else
- printk("request irq [ %d ] OK.\n", BDRV_IRQ);
- #endif
- return 0;
- }
- static irqreturn_t nt_boot_irq_handler(void)
- {
- int cpu_id = raw_smp_processor_id();
- if (boot_soter_flag == START_STATUS) {
- printk("boot irq handler if\n");
- boot_soter_flag = END_STATUS;
- up(&smc_lock);
- up(&(boot_sema));
- return IRQ_HANDLED;
- } else {
- printk("boot irq hanler else\n");
- if (forward_call_flag == GLSCH_NONE)
- forward_call_flag = GLSCH_NEG;
- else
- forward_call_flag = GLSCH_NONE;
- up(&smc_lock);
- up(&(boot_sema));
- return IRQ_HANDLED;
- }
- }
- void init_tlog_entry(void)
- {
- int i = 0;
- for (i = 0; i < TLOG_MAX_CNT; i++)
- tlog_ent[i].valid = TLOG_UNUSE;
- return;
- }
- int search_tlog_entry(void)
- {
- int i = 0;
- for (i = 0; i < TLOG_MAX_CNT; i++) {
- if (tlog_ent[i].valid == TLOG_UNUSE) {
- tlog_ent[i].valid = TLOG_INUSE;
- return i;
- }
- }
- return -1;
- }
- void tlog_func(struct work_struct *entry)
- {
- struct tlog_struct *ts = container_of(entry, struct tlog_struct, work);
- printk("TLOG %s", (char *)(ts->context));
- ts->valid = TLOG_UNUSE;
- return;
- }
- irqreturn_t tlog_handler(void)
- {
- int pos = 0;
- printk("~tlog handler~\n");
- pos = search_tlog_entry();
- if (-1 != pos) {
- memset(tlog_ent[pos].context, 0, TLOG_CONTEXT_LEN);
- memcpy(tlog_ent[pos].context, (char *)tlog_message_buff, TLOG_CONTEXT_LEN);
- Flush_Dcache_By_Area((unsigned long)tlog_message_buff, (unsigned long)tlog_message_buff + TLOG_CONTEXT_LEN);
- INIT_WORK(&(tlog_ent[pos].work), tlog_func);
- queue_work(secure_wq, &(tlog_ent[pos].work));
- }
- // irq_call_flag = GLSCH_HIGH;
- // up(&smc_lock);
- return IRQ_HANDLED;
- }
- int register_tlog_handler(void)
- {
- int retVal = 0;
- #ifdef CONFIG_OF
- int irq_num = 0;
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "microtrust,utos");
- irq_num = irq_of_parse_and_map(node, 1);
- retVal = request_irq(irq_num, tlog_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("[CONFIG_OF] [%s] ERROR for request_irq %d error code : %d.\n", __func__, irq_num, retVal);
- else
- printk("[CONFIG_OF] [%s] request irq [ %d ] OK.\n", __func__, irq_num);
- #else
- /* register 277 IRQ */
- retVal = request_irq(TEEI_LOG_IRQ, tlog_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("ERROR for request_irq %d error code : %d.\n", TEEI_LOG_IRQ, retVal);
- else
- printk("request irq [ %d ] OK.\n", TEEI_LOG_IRQ);
- #endif
- return 0;
- }
- int register_boot_irq_handler(void)
- {
- int retVal = 0;
- #ifdef CONFIG_OF
- int irq_num = 0;
- struct device_node *node;
- node = of_find_compatible_node(NULL, NULL, "microtrust,utos");
- irq_num = irq_of_parse_and_map(node, 4);
- retVal = request_irq(irq_num, nt_boot_irq_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("[CONFIG_OF] [%s] ERROR for request_irq %d error code : %d.\n", __func__, irq_num, retVal);
- else
- printk("[CONFIG_OF] [%s] request irq [ %d ] OK.\n", __func__, irq_num);
- #else
- /* register 283 IRQ */
- retVal = request_irq(BOOT_IRQ, nt_boot_irq_handler, 0, "tz_drivers_service", NULL);
- if (retVal)
- printk("ERROR for request_irq %d error code : %d.\n", BOOT_IRQ, retVal);
- else
- printk("request irq [ %d ] OK.\n", BOOT_IRQ);
- #endif
- return 0;
- }
- static void secondary_boot_stage2(void *info)
- {
- n_switch_to_t_os_stage2();
- }
- static void boot_stage2(void)
- {
- int cpu_id = 0;
- get_online_cpus();
- cpu_id = get_current_cpuid();
- smp_call_function_single(cpu_id, secondary_boot_stage2, NULL, 1);
- put_online_cpus();
- }
- int switch_to_t_os_stages2(void)
- {
- down(&(boot_sema));
- down(&(smc_lock));
- /* n_switch_to_t_os_stage2(); */
- boot_stage2();
- if (forward_call_flag == GLSCH_NONE)
- forward_call_flag = GLSCH_LOW;
- else if (forward_call_flag == GLSCH_NEG)
- forward_call_flag = GLSCH_NONE;
- else
- return -1;
- down(&(boot_sema));
- up(&(boot_sema));
- return 0;
- }
- static void secondary_load_tee(void *info)
- {
- n_invoke_t_load_tee(0, 0, 0);
- }
- static void load_tee(void)
- {
- int cpu_id = 0;
- get_online_cpus();
- cpu_id = get_current_cpuid();
- smp_call_function_single(cpu_id, secondary_load_tee, NULL, 1);
- put_online_cpus();
- }
- int t_os_load_image(void)
- {
- /* down the boot_sema. */
- down(&(boot_sema));
- /* N_INVOKE_T_LOAD_TEE to TOS */
- set_sch_load_img_cmd();
- down(&smc_lock);
- /* n_invoke_t_load_tee(0, 0, 0); */
- load_tee();
- /* start HIGH level glschedule. */
- if (forward_call_flag == GLSCH_NONE)
- forward_call_flag = GLSCH_LOW;
- else if (forward_call_flag == GLSCH_NEG)
- forward_call_flag = GLSCH_NONE;
- else
- return -1;
- /* block here until the TOS ack N_SWITCH_TO_T_OS_STAGE2 */
- down(&(boot_sema));
- up(&(boot_sema));
- return 0;
- }
- /**
- * @brief
- */
- static const struct file_operations teei_client_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = teei_client_ioctl,
- .compat_ioctl = teei_client_ioctl,
- .open = teei_client_open,
- .mmap = teei_client_mmap,
- .release = teei_client_release
- };
- #define TEEI_CONFIG_FULL_PATH_DEV_NAME "/dev/teei_config"
- #define TEEI_CONFIG_DEV "teei_config"
- #define TEEI_CONFIG_IOC_MAGIC 0x775B777E /* "TEEI Client" */
- /**
- * @brief Map the vma with the free pages
- *
- * @param filp
- * @param vma
- *
- * @return 0: success
- * EINVAL: Invalid parament
- * ENOMEM: No enough memory
- */
- static int teei_config_mmap(struct file *filp, struct vm_area_struct *vma)
- {
- return 0;
- }
- static int init_teei_framework(void);
- /**
- * @brief
- *
- * @param file
- * @param cmd
- * @param arg
- *
- * @return
- */
- #define TEEI_CONFIG_IOCTL_INIT_TEEI _IOWR(TEEI_CONFIG_IOC_MAGIC, 3, int)
- unsigned int teei_flags = 0;
- static long teei_config_ioctl(struct file *file, unsigned cmd, unsigned long arg)
- {
- int retVal = 0;
- void *argp = (void __user *) arg;
- switch (cmd) {
- case TEEI_CONFIG_IOCTL_INIT_TEEI:
- if (teei_flags == 1) {
- break;
- } else {
- init_teei_framework();
- teei_flags = 1;
- }
- break;
- default:
- printk("[%s][%d] command not found!\n", __func__, __LINE__);
- retVal = -EINVAL;
- }
- return retVal;
- }
- int is_teei_ready(void)
- {
- return teei_flags;
- }
- EXPORT_SYMBOL(is_teei_ready);
- /**
- * @brief The open operation of /dev/teei_config device node.
- *
- * @param inode
- * @param file
- *
- * @return ENOMEM: no enough memory in the linux kernel
- * 0: on success
- */
- static int teei_config_open(struct inode *inode, struct file *file)
- {
- return 0;
- }
- /**
- * @brief The release operation of /dev/teei_config device node.
- *
- * @param inode: device inode structure
- * @param file: struct file
- *
- * @return 0: on success
- */
- static int teei_config_release(struct inode *inode, struct file *file)
- {
- return 0;
- }
- /**
- * @brief
- */
- static const struct file_operations teei_config_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = teei_config_ioctl,
- .open = teei_config_open,
- .mmap = teei_config_mmap,
- .release = teei_config_release
- };
- static void secondary_teei_invoke_drv(void)
- {
- n_invoke_t_drv(0, 0, 0);
- return;
- }
- static void post_teei_invoke_drv(int cpu_id)
- {
- get_online_cpus();
- smp_call_function_single(cpu_id,
- secondary_teei_invoke_drv,
- NULL,
- 1);
- put_online_cpus();
- return;
- }
- static void teei_invoke_drv(void)
- {
- #if 0
- int cpu_id = smp_processor_id();
- /* int cpu_id = raw_smp_processor_id(); */
- if (cpu_id != 0) {
- /* call the mb function */
- mb();
- post_teei_invoke_drv(0); /* post it to primary */
- } else {
- /* printk("[%s][%d]\n", __func__, __LINE__); */
- n_invoke_t_drv(0, 0, 0); /* called directly on primary core */
- }
- #else
- int cpu_id = 0;
- cpu_id = get_current_cpuid();
- post_teei_invoke_drv(cpu_id);
- #endif
- return;
- }
- int __send_fp_command(unsigned long share_memory_size)
- {
- /* down(&smc_lock); */
- /* down(&boot_sema); */
- set_fp_command(share_memory_size);
- Flush_Dcache_By_Area((unsigned long)fp_buff_addr, fp_buff_addr + FP_BUFF_SIZE);
- /* Flush_Dcache_By_Area((unsigned long)vfs_flush_address, vfs_flush_address + VFS_SIZE); */
- #if 0
- teei_invoke_drv();
- #else
- fp_call_flag = GLSCH_HIGH;
- n_invoke_t_drv(0, 0, 0);
- #endif
- /* down(&boot_sema); */
- /* up(&boot_sema); */
- return 0;
- }
- struct fp_command_struct {
- unsigned long mem_size;
- int retVal;
- };
- struct fp_command_struct fp_command_entry;
- static void secondary_send_fp_command(void *info)
- {
- struct fp_command_struct *cd = (struct fp_command_struct *)info;
- /* with a rmb() */
- rmb();
- cd->retVal = __send_fp_command(cd->mem_size);
- /* with a wmb() */
- wmb();
- }
- int send_fp_command(unsigned long share_memory_size)
- {
- int cpu_id = 0;
- int retVal = 0;
- struct fdrv_call_struct fdrv_ent;
- down(&fp_lock);
- mutex_lock(&pm_mutex);
-
- if (teei_config_flag == 1) {
- complete(&global_down_lock);
- }
- down(&smc_lock);
- down(&boot_sema);
- #if 0
- fp_command_entry.mem_size = share_memory_size;
- #else
- fdrv_ent.fdrv_call_type = FP_SYS_NO;
- fdrv_ent.fdrv_call_buff_size = share_memory_size;
- #endif
- /* with a wmb() */
- wmb();
- #if 0
- get_online_cpus();
- cpu_id = get_current_cpuid();
- smp_call_function_single(cpu_id, secondary_send_fp_command, (void *)(&fp_command_entry), 1);
- put_online_cpus();
- #else
- Flush_Dcache_By_Area((unsigned long)&fdrv_ent, (unsigned long)&fdrv_ent + sizeof(struct fdrv_call_struct));
- retVal = add_work_entry(FDRV_CALL, (unsigned long)&fdrv_ent);
- if (retVal != 0) {
- mutex_unlock(&pm_mutex);
- up(&fp_lock);
- return retVal;
- }
- #endif
- down(&boot_sema);
- up(&boot_sema);
- rmb();
- mutex_unlock(&pm_mutex);
- up(&fp_lock);
- return fdrv_ent.retVal;
- }
- struct boot_stage1_struct {
- unsigned long vir_addr;
- };
- struct boot_stage1_struct boot_stage1_entry;
- static void secondary_boot_stage1(void *info)
- {
- struct boot_stage1_struct *cd = (struct boot_stage1_struct *)info;
- /* with a rmb() */
- rmb();
- n_init_t_boot_stage1(cd->vir_addr, 0, 0);
- /* with a wmb() */
- wmb();
- }
- static void boot_stage1(unsigned long vir_address)
- {
- int cpu_id = 0;
- boot_stage1_entry.vir_addr = vir_address;
- /* with a wmb() */
- wmb();
- get_online_cpus();
- cpu_id = get_current_cpuid();
- printk("current cpu id [%d]\n", cpu_id);
- smp_call_function_single(cpu_id, secondary_boot_stage1, (void *)(&boot_stage1_entry), 1);
- put_online_cpus();
- /* with a rmb() */
- rmb();
- }
- /**
- * @brief init TEEI Framework
- * init Soter OS
- * init Global Schedule
- * init Forward Call Service
- * init CallBack Service
- * @return
- */
- static int init_teei_framework(void)
- {
- long retVal = 0;
- int i = 0;
- unsigned long secure_mem_p = 0;
- boot_soter_flag = START_STATUS;
- sema_init(&(boot_sema), 1);
- sema_init(&(fp_lock), 1);
- sema_init(&(api_lock), 1);
- register_boot_irq_handler();
- register_sched_irq_handler();
- register_switch_irq_handler();
- register_soter_irq_handler();
- register_fp_ack_handler();
- register_bdrv_handler();
- register_tlog_handler();
- register_error_irq_handler();
- secure_wq = create_workqueue("Secure Call");
- daulOS_VFS_write_share_mem = kmalloc(VDRV_MAX_SIZE, GFP_KERNEL);
- if (daulOS_VFS_write_share_mem == NULL) {
- printk("[%s][%d] kmalloc daulOS_VFS_write_share_mem failed!\n", __func__, __LINE__);
- return -1;
- }
- daulOS_VFS_read_share_mem = kmalloc(VDRV_MAX_SIZE, GFP_KERNEL);
- if (daulOS_VFS_read_share_mem == NULL) {
- printk("[%s][%d] kmalloc daulOS_VFS_read_share_mem failed!\n", __func__, __LINE__);
- return -1;
- }
- printk("[%s][%d]\n", __func__, __LINE__);
- printk("[%s][%d] VFS_SIZE = %d, SZ_4K = %d\n", __func__, __LINE__, VFS_SIZE, SZ_4K);
- printk("[%s][%d] ROUND_UP(VFS_SIZE, SZ_4K) = %d\n", __func__, __LINE__, ROUND_UP(VFS_SIZE, SZ_4K));
- printk("[%s][%d] get_order(ROUND_UP(VFS_SIZE, SZ_4K)) = %d\n", __func__, __LINE__, get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
- boot_vfs_addr = (unsigned long) __get_free_pages(GFP_KERNEL | GFP_DMA , get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
- printk("[%s][%d]\n", __func__, __LINE__);
- if (boot_vfs_addr == NULL) {
- printk("[%s][%d]ERROR: There is no enough memory for booting Soter!\n", __func__, __LINE__);
- return -1;
- }
- printk("[%s][%d]\n", __func__, __LINE__);
- down(&(boot_sema));
- down(&(smc_lock));
- printk("[%s][%d]\n", __func__, __LINE__);
- /* n_init_t_boot_stage1((unsigned long)virt_to_phys(boot_vfs_addr), 0, 0); */
- boot_stage1((unsigned long)virt_to_phys(boot_vfs_addr));
- down(&(boot_sema));
- up(&(boot_sema));
- free_pages(boot_vfs_addr, get_order(ROUND_UP(VFS_SIZE, SZ_4K)));
- boot_soter_flag = END_STATUS;
- if (soter_error_flag == 1) {
- return -1;
- }
- /**printk("[%s][%d] begin to load Soter services.\n", __func__, __LINE__);
- **switch_to_t_os_stages2();
- **printk("[%s][%d] load Soter services successfully.\n", __func__, __LINE__);*/
- printk("[%s][%d] begin to create the command buffer!\n", __func__, __LINE__);
- retVal = create_cmd_buff();
- if (retVal < 0) {
- printk("[%s][%d] create_cmd_buff failed !\n", __func__, __LINE__);
- return retVal;
- }
- printk("[%s][%d] end of creating the command buffer!\n", __func__, __LINE__);
- printk("[%s][%d] begin to load Soter services.\n", __func__, __LINE__);
- switch_to_t_os_stages2();
- printk("[%s][%d] load Soter services successfully.\n", __func__, __LINE__);
- if (soter_error_flag == 1) {
- return -1;
- }
- init_smc_work();
- printk("[%s][%d] begin to init daulOS services.\n", __func__, __LINE__);
- retVal = teei_service_init();
- if (retVal == -1)
- return -1;
- printk("[%s][%d] init daulOS services successfully.\n", __func__, __LINE__);
- printk("[%s][%d] begin to load TEEs.\n", __func__, __LINE__);
- t_os_load_image();
- if (soter_error_flag == 1)
- return -1;
- printk("[%s][%d] load TEEs successfully.\n", __func__, __LINE__);
- teei_config_flag = 1;
- return 0;
- }
- static dev_t teei_config_device_no;
- static struct cdev teei_config_cdev;
- static struct class *config_driver_class;
- /**
- * @brief TEEI Agent Driver initialization
- * initialize Microtrust Tee environment
- * @return
- **/
- static int teei_config_init(void)
- {
- int ret_code = 0;
- long retVal = 0;
- struct device *class_dev = NULL;
- ret_code = alloc_chrdev_region(&teei_config_device_no, 0, 1, TEEI_CONFIG_DEV);
- if (ret_code < 0) {
- printk("alloc_chrdev_region failed %x.\n", ret_code);
- return ret_code;
- }
- config_driver_class = class_create(THIS_MODULE, TEEI_CONFIG_DEV);
- if (IS_ERR(config_driver_class)) {
- ret_code = -ENOMEM;
- printk("class_create failed %x\n", ret_code);
- goto unregister_chrdev_region;
- }
- class_dev = device_create(config_driver_class, NULL, teei_config_device_no, NULL, TEEI_CONFIG_DEV);
- if (NULL == class_dev) {
- printk("class_device_create failed %x\n", ret_code);
- ret_code = -ENOMEM;
- goto class_destroy;
- }
- cdev_init(&teei_config_cdev, &teei_config_fops);
- teei_config_cdev.owner = THIS_MODULE;
- ret_code = cdev_add(&teei_config_cdev, MKDEV(MAJOR(teei_config_device_no), 0), 1);
- if (ret_code < 0) {
- printk("cdev_add failed %x\n", ret_code);
- goto class_device_destroy;
- }
- goto return_fn;
- class_device_destroy:
- device_destroy(driver_class, teei_config_device_no);
- class_destroy:
- class_destroy(driver_class);
- unregister_chrdev_region:
- unregister_chrdev_region(teei_config_device_no, 1);
- return_fn:
- return ret_code;
- }
- static int teei_cpu_id[] = {0x0000, 0x0001, 0x0002, 0x0003, 0x0100, 0x0101, 0x0102, 0x0103};
- static int __cpuinit tz_driver_cpu_callback(struct notifier_block *self,
- unsigned long action, void *hcpu)
- {
- unsigned int cpu = (unsigned long)hcpu;
- /*unsigned int sched_cpu = 4;*/
- unsigned int sched_cpu = get_current_cpuid();
- struct cpumask mtee_mask = { CPU_BITS_NONE };
- int retVal = 0;
- int i;
- switch (action) {
- case CPU_DOWN_PREPARE:
- case CPU_DOWN_PREPARE_FROZEN:
- if (cpu == sched_cpu) {
- printk("cpu down prepare ************************\n");
- retVal = down_trylock(&smc_lock);
- if (retVal == 1) {
- return NOTIFY_BAD;
- }
- else {
- cpu_notify_flag = 1;
- for_each_online_cpu(i) {
- printk("current on line cpu [%d]\n", i);
- if (i == cpu) {
- continue;
- }
- current_cpu_id = i;
- }
- #if 1
- printk("[%s][%d]brefore cpumask set cpu\n", __func__, __LINE__);
- cpumask_set_cpu(current_cpu_id, &mtee_mask);
- /*cpumask_set_cpu(current_cpu_id, &mask);*/
- printk("[%s][%d]after cpumask set cpu\n", __func__, __LINE__);
- #if 0
- if (sched_setaffinity(sub_pid, &mtee_mask) == -1)
- printk("warning: could not set CPU affinity, continuing...\n");
- #endif
- set_cpus_allowed(teei_switch_task, mtee_mask);
- #endif
- /* TODO smc_call to notify ATF to switch the CPU*/
- /* NT_switch_T(current_cpu_id);*/
- printk("current cpu id \n");
- nt_sched_core(teei_cpu_id[current_cpu_id], teei_cpu_id[cpu], 0);
- printk("change cpu id = [%d]\n", current_cpu_id);
- }
- }
- break;
- case CPU_DOWN_FAILED:
- if (cpu_notify_flag == 1) {
- printk("cpu down failed *************************\n");
- up(&smc_lock);
- cpu_notify_flag = 0;
- }
- break;
- case CPU_DEAD:
- case CPU_DEAD_FROZEN:
- if (cpu_notify_flag == 1) {
- printk("cpu down success ***********************\n");
- up(&smc_lock);
- cpu_notify_flag = 0;
- }
- break;
- }
- return NOTIFY_OK;
- }
- /**
- * @brief TEEI Agent Driver initialization
- * initialize service framework
- * @return
- */
- static int teei_client_init(void)
- {
- int ret_code = 0;
- long retVal = 0;
- struct device *class_dev = NULL;
- long prior = 0;
- unsigned long irq_status = 0;
- /* printk("TEEI Agent Driver Module Init ...\n"); */
- printk("=============================================================\n\n");
- printk("~~~~~~~uTos version [%s]~~~~~~~\n",UTOS_VERSION);
- printk("=============================================================\n\n");
- ret_code = alloc_chrdev_region(&teei_client_device_no, 0, 1, TEEI_CLIENT_DEV);
- if (ret_code < 0) {
- printk("alloc_chrdev_region failed %x\n", ret_code);
- return ret_code;
- }
- driver_class = class_create(THIS_MODULE, TEEI_CLIENT_DEV);
- if (IS_ERR(driver_class)) {
- ret_code = -ENOMEM;
- printk("class_create failed %x\n", ret_code);
- goto unregister_chrdev_region;
- }
- class_dev = device_create(driver_class, NULL, teei_client_device_no, NULL, TEEI_CLIENT_DEV);
- if (NULL == class_dev) {
- printk("class_device_create failed %x\n", ret_code);
- ret_code = -ENOMEM;
- goto class_destroy;
- }
- cdev_init(&teei_client_cdev, &teei_client_fops);
- teei_client_cdev.owner = THIS_MODULE;
- ret_code = cdev_add(&teei_client_cdev, MKDEV(MAJOR(teei_client_device_no), 0), 1);
- if (ret_code < 0) {
- printk("cdev_add failed %x\n", ret_code);
- goto class_device_destroy;
- }
- memset(&teei_contexts_head, 0, sizeof(teei_contexts_head));
- teei_contexts_head.dev_file_cnt = 0;
- init_rwsem(&teei_contexts_head.teei_contexts_sem);
- INIT_LIST_HEAD(&teei_contexts_head.context_list);
- init_tlog_entry();
- sema_init(&(smc_lock), 1);
- //sema_init(&(global_down_lock), 0);
- int i;
- for_each_online_cpu(i) {
- current_cpu_id = i;
- printk("init stage : current_cpu_id = %d\n", current_cpu_id);
- }
- printk("begin to create sub_thread.\n");
- #if 0
- sub_pid = kernel_thread(global_fn, NULL, CLONE_KERNEL);
- retVal = sys_setpriority(PRIO_PROCESS, sub_pid, -3);
- #else
- //struct sched_param param = {.sched_priority = -20 };
- teei_fastcall_task = kthread_create(global_fn, NULL, "teei_fastcall_thread");
- if (IS_ERR(teei_fastcall_task)) {
- printk("create fastcall thread failed: %d\n", PTR_ERR(teei_fastcall_task));
- goto fastcall_thread_fail;
- }
- //sched_setscheduler_nocheck(teei_fastcall_task, SCHED_NORMAL, ¶m);
- //get_task_struct(teei_fastcall_task);
- wake_up_process(teei_fastcall_task);
- #endif
- printk("create the sub_thread successfully!\n");
- #if 0
- cpumask_set_cpu(get_current_cpuid(), &mask);
- retVal = sched_setaffinity(sub_pid, &mask);
- if (retVal != 0)
- printk("warning: could not set CPU affinity, retVal = [%l] continuing...\n", retVal);
- #endif
- /* create the switch thread */
- teei_switch_task = kthread_create(kthread_worker_fn, &ut_fastcall_worker, "teei_switch_thread");
- if (IS_ERR(teei_switch_task)) {
- printk("create switch thread failed: %ld\n", PTR_ERR(teei_switch_task));
- teei_switch_task = NULL;
- goto fastcall_thread_fail;
- }
- //sched_setscheduler_nocheck(teei_switch_task, SCHED_NORMAL, ¶m);
- //get_task_struct(teei_switch_task);
- wake_up_process(teei_switch_task);
- cpumask_set_cpu(get_current_cpuid(), &mask);
- set_cpus_allowed(teei_switch_task, mask);
- register_cpu_notifier(&tz_driver_cpu_notifer);
- printk("after register cpu notify\n");
- teei_config_init();
- goto return_fn;
- fastcall_thread_fail:
- class_device_destroy:
- device_destroy(driver_class, teei_client_device_no);
- class_destroy:
- class_destroy(driver_class);
- unregister_chrdev_region:
- unregister_chrdev_region(teei_client_device_no, 1);
- return_fn:
- return ret_code;
- }
- /**
- * @brief
- */
- static void teei_client_exit(void)
- {
- TINFO("teei_client exit");
- device_destroy(driver_class, teei_client_device_no);
- class_destroy(driver_class);
- unregister_chrdev_region(teei_client_device_no, 1);
- }
- MODULE_LICENSE("GPL v2");
- MODULE_AUTHOR("TEEI <www.microtrust.com>");
- MODULE_DESCRIPTION("TEEI Agent");
- MODULE_VERSION("1.00");
- module_init(teei_client_init);
- module_exit(teei_client_exit);
|