/** * @brief Interrupt handler for echo task * * This function set the variable to implement the functionality of notification * meachanism. * * @param interrupt: Interrupt ID * @param data: TLS data */ void echo_task_handler(struct timer_event* tevent) { void* data = tevent->data; sw_tls *tls; struct echo_global *echo_data; u32 task_id = (u32) data; sw_printf("SW: echo task handler 0x%x\n", task_id); tls = get_task_tls(task_id); if(tls) { echo_data = (struct echo_global *)tls->private_data; echo_data->data_available = 1; } if(tls) { notify_ns(task_id); } else { sw_printf("SW: where is the task???\n"); } tevent->state &= ~TIMER_STATE_EXECUTING; timer_event_destroy(tevent); }
void print_uint8 (uint8x16_t data, char* name) { int i; static uint8_t p[16]; vst1q_u8 (p, data); sw_printf ("%s = ", name); for (i = 0; i < 16; i++) { sw_printf ("%02d ", p[i]); } sw_printf ("\n"); }
/** * @brief * This function wakes up the task but does not set the condition * So the task will go back to sleep again. * This function is called from Timer Interrupt handler * @param tevent */ void test_wq_noset_condition(struct timer_event* tevent) { void* data = tevent->data; u32 task_id = (u32)data; sw_printf("SW: No Set condition Int Handler\n"); struct sw_task* task = get_task(task_id); sw_printf("SW: Calling wakeup task from Int handler \n"); sw_wakeup(&task->wq_head, WAKE_UP); sw_printf("SW: Called wakeup task from Int handler \n"); tevent->state &= ~TIMER_STATE_EXECUTING; timer_event_destroy(tevent); }
/** * @brief * This function wakes up the task which has called sleep * * @param tevent * The timer_event structure used for putting this function to sleep */ void wake_up_from_sleep(struct timer_event* tevent) { int task_id = *(int*)(tevent->data); #ifdef TIMER_DBG sw_printf("SW: wake up from sleep\n"); sw_printf("SW: task id %x\n",task_id); #endif /* This is called from interrupt context so no locking may require */ schedule_task_id(task_id); tevent->state &= ~TIMER_STATE_EXECUTING; timer_event_destroy(tevent); return; }
int sdramtest(int argc, char *argv[]) { int *addr = (int *)0x40008000; int *endaddr = (int *)0x44000000; int *p; sw_sdram_init(); while(1){ p = addr; while(p < endaddr){ *p = (int)p; p += STEP; } p = addr; while(p < endaddr){ sw_printf("%x: %x\n\r", (int)p, *p); p += STEP; sw_usleep(1 * 1000); } } return 0; }
/** * @brief : Loads the sections marked with SHF_ALLOC flags into memory * * @param file_map : memory map of the entire relocatable object file * @param sec_header : pointer to the section header table * * @return 0 on success , -1 on failure */ static int load_into_memory(void *file_map , Elf32_Shdr * sec_header) { Elf32_Ehdr *elf_header = (Elf32_Ehdr *)file_map; Elf32_Shdr *tmp_shdr = sec_header; void *status = NULL; int shnum = elf_header->e_shnum,i; u32 prev_addr = BASE_LOAD_ADDRESS; for(i = 1; i < shnum ; i++){ if(tmp_shdr[i].sh_flags & SHF_ALLOC){ status = sw_memcpy((void *)prev_addr, (void*)tmp_shdr[i].sh_addr, tmp_shdr[i].sh_size); if(status == NULL){ sw_printf("load failed\n"); return -1; } prev_addr += tmp_shdr[i].sh_size; } } return 0; }
/** * @brief Echo task entry point * * This function implements the commands to echo the input buffer using copying * the buffer and using shared memory * * @param task_id: task identifier * @param tls: Pointer to task local storage */ void echo_task(int task_id, sw_tls* tls) { tls->ret_val = 0; #ifdef ECHO_TIMER_TEST struct timer_event* tevent1; #endif #ifdef WQ_TEST_FUNC test_wait_queue(task_id); #endif #ifdef ECHO_TIMER_TEST tevent1 = timer_event_create(&echo_task_handler,(void*)task_id); if(!tevent1){ sw_printf("SW: Out of Memory : Cannot register Handler\n"); return; } time.tval.nsec = 1000; time.tval.sec = 0; timer_event_start(tevent1, time); #endif tls->ret_val = process_otzapi(task_id, tls); #ifdef ECHO_IPC_TEST ipc_test_crypto(OTZ_SVC_ECHO, task_id); #endif handle_task_return(task_id, tls); DIE_NOW(0, "echo task - hangs\n"); }
/** * @brief Trustzone hypervisor initialization * * @return */ int tzhyp_init(void) { int error; error = tzhyp_nsadmin_init(); if (error < 0) { sw_printf("tzhyp: nsadmin init failed\n"); return error; } error = tzhyp_guest_init(); if (error < 0) { sw_printf("tzhyp: guest init failed\n"); return error; } return 0; }
/** * @brief * * @return */ int secure_boot(void) { struct mmc *mmc; int blocks = SECURE_OS_SIZE/512; serial_init(0); serial_puts("\r\nSW: Entering Secure Boot \r\n"); enable_l1_cache(); if(mmc_initialize()) { DIE_NOW(0, "mmc initialize failed"); } int k = 0, ret_blkcnt; mmc = find_mmc_device(0); block_dev_desc_t *block_dev = &mmc->block_dev; emmc_boot_open(mmc); for (k = 0; k < blocks; k++) { ret_blkcnt = block_dev->block_read(block_dev->dev, k+SECURE_OS_MMC_START_SECTOR, 1, (void*)((u32)g_buffer + k * 512)); if(ret_blkcnt != 1) { sw_printf("error in reading block 0x%x\n", k); } #ifdef SW_BL_DBG if( k == 0 || k == blocks -1) { for(i=0; i<32; i++){ sw_printf(" %02x |", *(g_buffer + k * 512 + i)); if(j++ == 4){ j=0; sw_printf("!\n"); } } sw_printf("!\n"); } #endif } emmc_boot_close(mmc); sw_printf("jump to secure OS\n"); jump_to(); while(1); return OTZ_OK; }
/* * Before call this funtion, you SHOULD have initialize uartdbg. * * Receive data from host * @return: bytes of receive data */ unsigned int sw_xmodem_rec(unsigned int addr) { int c; int i; int count; char *xbuf; xbuf = (char *)addr; count = 0; sw_printf("Countdown to receive data, you have 10 seconds..."); for(i = 9; i >= 0; i--) { sw_usleep(1000 * 1000); sw_printf("%u ", i); } sw_putchar(XMODEM_NAK); //start transfer for(;;){ c = sw_getchar(); if(c == XMODEM_EOT){ break; } if(c != XMODEM_SOH){ continue; } sw_getchar(); /* eat package number */ sw_getchar(); /* eat package ~number */ for(i = 0; i < 128; i++){ *xbuf++ = sw_getchar(); } sw_getchar(); /* eat check byte */ sw_putchar(XMODEM_ACK); } sw_putchar(XMODEM_ACK); return count; }
/** * @brief * This function sleeps for given number of seconds * @param secs * Number of secs to sleep */ void sw_sleep(u32 secs) { timeval_t time; time.tval.nsec = 0; time.tval.sec = secs; # ifndef CONFIG_EMULATE_FIQ int current_context; struct timer_event *tevent; current_context = get_current_task_id(); #ifdef TIMER_DBG sw_printf("SW: sleep sec 0x%08x nsec 0x%08x \n",time.tval.sec,time.tval.nsec); #endif tevent = timer_event_create(&wake_up_from_sleep, ¤t_context); if(!tevent){ sw_printf("SW: Out of memory : Cannot Perform Sleep\n"); return; } timer_event_start(tevent, &time); suspend_task(current_context, TASK_STATE_WAIT); schedule(); # else u32 clockcycles = timeval_to_clockcycles(&time); #ifdef TIMER_DBG sw_printf("SW: clockcycles 0x%08x \n",clockcycles); #endif enable_timer(); while(1){ u32 curr_val = read_sleep_timer(); if(curr_val > clockcycles){ break; } } disable_timer(); # endif return; }
int stdiotest(int argc, char *argv[]) { unsigned int i; for(i = 0xfafafafa; i < 0xffffffff; i+=0xff){ sw_printf("[%u] = %x\n\r", i, i); } return 0; }
/** * @brief * Copies the values of Num bytes from the location pointed by source directly * to the memory block pointed by destination By checking the values of * Num bytes with destination and source Maximum Length * * @param dst - Pointer to the destination array where the content is to be * copied * @param src - Pointer to the source of data to be copied * @param count - Number of bytes to copy * @param dstLen - destination Maximum Length * @param srcLen - source Maximum Length * * @return */ void *sw_memncpy(void *dst, const void *src, u32 count,u32 dstLen,u32 srcLen) { if(count<=dstLen || count<=srcLen) { return sw_memcpy(dst,src,count); } else { sw_printf("Memory Overflow Error\n"); return NULL; } }
/** * @brief * This function initializes the waitqueue and put itself to a waitqueue. * It also registers timer handlers whill will set the condition and wakes * up the task again * @param task_id */ void test_wait_queue(int task_id) { wq_test_var = 0; struct sw_task* task = get_task(task_id); struct timer_event *tevent,*tevent1; timeval_t time; tevent = timer_event_create(&test_wq_set_condition,(void*)task_id); time.tval.sec = 0; time.tval.nsec = 10000000;/*10ms*/ timer_event_start(tevent, &time); tevent1 = timer_event_create(&test_wq_noset_condition,(void*)task_id); time.tval.sec = 0; time.tval.nsec = 1000000;/*1ms*/ timer_event_start(tevent1, &time); task->wq_head.elements_count = 0; INIT_LIST_HEAD(&task->wq_head.elements_list); #ifdef ECHO_DBG sw_printf("SW: Before calling wait event \n"); sw_wait_event(&task->wq_head, (wq_test_var==1)); sw_printf("SW: Coming out from wait event \n"); #endif struct wait_queue wq; /*sw_init_waitqueue_entry(&wq);*/ sw_init_waitqueue_entry_func(&wq, &test_wq_dummy_wakeup_function); sw_add_to_waitqueue(&task->wq_head,&wq); sw_printf("SW: Before putting the task to sleep in waitqueue \n"); while(!(wq_test_var==1)){ sw_set_task_state(TASK_STATE_WAIT); schedule(); } sw_printf("SW: coming out of sleep from waitqueue \n"); sw_remove_from_waitqueue(&task->wq_head,&wq); }
/** * @brief clean up function to remove the mappings * * @param psa_config * * @return 0 on success , -1 on failure */ int elf_loader_cleanup(void) { int status = 0; /* 0 indicates that the mapping is successful, so do the cleanup */ status = unmap_secure_memory((va_t)BASE_LOAD_ADDRESS, SECTION_SIZE); if (status == -1){ sw_printf("Unable to unmap secure memory of elf loader\n"); return -1; } return status; }
bool ProcDebugBGL::debug_post_attach(ThreadState *) { if (executable_path.empty()) { char *jobid = getenv("BG_JOBID"); if (jobid) { ostringstream linkstream; linkstream << "/jobs/" << jobid << "/exe"; string linkname(linkstream.str()); executable_path = deref_link(linkname.c_str()); sw_printf("[%s:%u] - Set executable path to %s\n", FILE__, __LINE__, executable_path.c_str()); } } library_tracker = new StaticBinaryLibState(this, executable_path); return true; }
/*TEE_Result TEE_CheckMemoryAccessRights( u32 accessFlags, void* buffer, size_t size) { return TEE_SUCCESS; } void TEE_SetInstanceData( void* instanceData ) { Data = instanceData; } void* TEE_GetInstanceData( void ) { return Data; } */ void* TEE_Malloc( size_t size, u32 hint ) { void* buffer; if((buffer = malloc(size))==NULL) { sw_printf("Memory Allocation Failed\n"); return NULL; } if(hint == 0x0) { sw_memset(buffer, 0, size); } /*else { hint in the range [0x00000001, 0xFFFFFFFF] can be used in future versions. }*/ return buffer; }
int echo_task_init(sa_config_t *psa_config) { sw_memset(psa_config, 0x0, sizeof(sa_config_t)); psa_config->service_uuid = OTZ_SVC_ECHO; sw_strcpy(psa_config->service_name, "echo"); psa_config->stack_size = TASK_STACK_SIZE; psa_config->data = (void*)sw_malloc(sizeof(struct echo_global)); if(!psa_config->data) { sw_printf("SW: echo task init: allocation of local storage data failed\n"); return OTZ_ENOMEM; } psa_config->entry_point = &echo_task; psa_config->process = (u32)&process_otz_echo_svc; sw_memset(psa_config->data, 0, sizeof(struct echo_global)); return OTZ_OK; }
/** * @brief Dispatcher task init * * This function initializes dispatcher task parameters and its get called * before the task creation * * @param psa_config: Configuration parameter for the task * * @return otz_return_t: * OTZ_OK \n * OTZ_FAIL \n */ int dispatch_task_init(sa_config_t *psa_config) { sw_memset(psa_config, 0x0, sizeof(sa_config_t)); psa_config->service_uuid = OTZ_SVC_GLOBAL; sw_strcpy(psa_config->service_name, "dispatcher"); psa_config->stack_size = TASK_STACK_SIZE; psa_config->entry_point = (u32) &dispatch_task; psa_config->data = (void *)sw_malloc_private(COMMON_HEAP_ID, sizeof(struct dispatch_global)); if(!psa_config->data) { sw_printf("SW: dispatch task init: allocation of local storage data failed\n"); return OTZ_ENOMEM; } sw_memset(psa_config->data, 0 , sizeof(struct dispatch_global)); g_dispatch_data = psa_config->data; /* INIT_LIST_HEAD( &((struct dispatch_global*)psa_config->data)->pending_list); */ return OTZ_OK; }
/** * @brief writes nmemb elements of data, each size bytes long, * to the stream pointed to by stream, obtaining them * from the location given by ptr * * @param file file descriptor of the file * @param ptr contains data to be write in a file * @param len length of data to be read * * @return the number of items successfully read * If an error occurs, or the end-of-file is reached * the return value is a short item count (or zero) */ int _write(int file, char *ptr, int len) { int todo = 0; u8 *local_buff = NULL; if((file_pointers[file].fd == SW_STDERR) || (file_pointers[file].fd == SW_STDOUT) || (file_pointers[file].fd == SW_STDIN)) { if((local_buff = (u8*)sw_malloc((len+1)*sizeof(u8))) != NULL) { sw_memcpy(local_buff,ptr,len); local_buff[len] = '\0'; sw_printf((char*)local_buff); sw_free(local_buff); } /*for (todo = 0; todo < len; todo++) { UART_DR(UART0_ADDR) = *ptr++; }*/ todo = len; } else { #ifdef CONFIG_FILESYSTEM_SUPPORT if(file_names[file][0] == '\0') { errno = EBADF; return(-1); } todo=file_write(file_pointers[file].fd,ptr,len); #else sw_printk("file system configuration is not defined. \ Enable CONFIG_FILESYSTEM_SUPPORT.\n"); errno= EBADF; return (-1); #endif } errno = 0; return(todo); }
/** * @brief */ void test_storage_api() { uint32_t storageID=TEE_OBJECT_STORAGE_PRIVATE, r_flags=TEE_DATA_FLAG_ACCESS_READ, w_flags=TEE_DATA_FLAG_ACCESS_WRITE, rw_flags=(TEE_DATA_FLAG_ACCESS_READ | TEE_DATA_FLAG_ACCESS_WRITE), a_attribute_val=0x00000005,b_attribute_val=0x00000007, pop_ret_val,attribute_cnt=0x00000003,seek_ret_val,open_seek_retval, crt_ret_val,write_ret_val,open_write_retval,read_ret_val, open_read_retval,open_ret_val,open_delete_retval,allocate1_ret_val, allocate2_ret_val,rd_trunc_cnt=0x00000000,open_truncate_retval, trunc_size=0x0000000A,truncate_ret_val,rdtest_truncated_retval, optest_truncated_retval,rdtest_written_retval, optest_written_retval,rd_write_cnt=0x00000000,read_cnt=0x00000000, trunc_cnt=0x00000000,open_rename_retval,de_a, rd_rename_cnt=0x00000000,optest_renamed_retval,rename_ret_val, rdtest_renamed_retval,optest_deleted_retval; typedef signed int int32_t; int32_t offset=0x00000003; size_t objectIDLen=0x00000040,read_size=0x0000000F,rd_trunc_size=0x0000000A, rd_write_size=0x0000002C,rd_rename_size=0x0000000C; void* open_objectID="/test.dir/test.txt"; void* rename_objectID="/test.dir/new.txt"; void* initialData="This a sierraware created sample initial data\n"; void* create_objectID="/test.dir/crt.txt"; void* read_objectID="/test.dir/read.txt"; void* write_objectID="/test.dir/write.txt"; void* seek_objectID="/test.dir/seek.txt"; void* delete_objectID="/test.dir/delete.txt"; void* trunc_objectID="/test.dir/truncate.txt"; char wrie_buffer[255]={"This a sierraware created sample test string\n"}; char read_buffer[255],rd_trunc_buffer[255],rd_write_buffer[255], rd_rename_buffer[255]; void* attrsbuffer="This will get populated sometimes in the test fn\n"; void* p_buffer="And finally we tested GP_INTERNAL_STORAGE APP\n"; TEE_ObjectHandle crtattributes; TEE_ObjectHandle *first_object; TEE_ObjectHandle *second_object; TEE_Whence whence; whence=0x00000000; sw_printf("-----------Allocating Memory For Create Object--------------\n"); first_object=(TEE_ObjectHandle*)TEE_Malloc(sizeof(TEE_ObjectHandle),0); sw_printf("-------Allocating Memory For Create Object members----------\n"); allocate1_ret_val=TEE_AllocateTransientObject(TEE_TYPE_AES,0x00000800, first_object); sw_printf("the allocate transient function returns value is %x \n", allocate1_ret_val); crt_ret_val=TEE_CreatePersistentObject(storageID,create_objectID, objectIDLen,w_flags,crtattributes,initialData, (size_t)(sw_strlen((char*)initialData)),first_object); sw_printf("The create Persistent object funtion \ returns value is %x \n \n",crt_ret_val); sw_printf("------------Allocating Memory For open Object---------------\n"); second_object=(TEE_ObjectHandle*)TEE_Malloc(sizeof(TEE_ObjectHandle),0); sw_printf("------------Allocating Memory For open Object members-------\n"); allocate2_ret_val=TEE_AllocateTransientObject(TEE_TYPE_RSA_KEYPAIR, 0x00000800,second_object); sw_printf("the allocate transient function returns value is %x \n", allocate2_ret_val); open_ret_val=TEE_OpenPersistentObject(storageID,open_objectID,objectIDLen, r_flags,second_object); sw_printf("The open Persistent object funtion returns value is %x \n \n", open_ret_val); sw_printf("*****Reset the open object***** \n"); TEE_ResetTransientObject(*second_object); open_read_retval=TEE_OpenPersistentObject(storageID,read_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_read_retval); read_ret_val=TEE_ReadObjectData(*second_object,(void*)&read_buffer, read_size,&read_cnt); sw_printf("The Read Persistent funtion returns value is %x \n \n", read_ret_val); sw_printf("*****Reset the read object***** \n"); TEE_ResetTransientObject(*second_object); open_write_retval=TEE_OpenPersistentObject(storageID,write_objectID, objectIDLen,w_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_write_retval); write_ret_val=TEE_WriteObjectData(*second_object,(void*)&wrie_buffer, (size_t)(sw_strlen((char*)&wrie_buffer))); sw_printf("The write Persistent funtion returns value is %x \n \n", write_ret_val); sw_printf("*****Reset the write object***** \n"); TEE_ResetTransientObject(*second_object); optest_written_retval=TEE_OpenPersistentObject(storageID,write_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",optest_written_retval); rdtest_written_retval=TEE_ReadObjectData(*second_object, (void*)&rd_write_buffer,rd_write_size, &rd_write_cnt); sw_printf("The Read Persistent funtion returns value is %x \n \n", rdtest_written_retval); sw_printf("******TESTING:write persistent object*******\n"); if(rdtest_written_retval==1) { sw_printf("SUCCESS \n"); } else { sw_printf("FAILURE \n"); } sw_printf("*****Reset the read object***** \n"); TEE_ResetTransientObject(*second_object); open_truncate_retval=TEE_OpenPersistentObject(storageID,trunc_objectID, objectIDLen,w_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_truncate_retval); truncate_ret_val=TEE_TruncateObjectData(*second_object,trunc_size); sw_printf("The truncate Persistent funtion returns value is %x \n \n", truncate_ret_val); sw_printf("*****Reset the truncate object***** \n"); TEE_ResetTransientObject(*second_object); optest_truncated_retval=TEE_OpenPersistentObject(storageID,trunc_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",optest_truncated_retval); rdtest_truncated_retval=TEE_ReadObjectData(*second_object, (void*)&rd_trunc_buffer,rd_trunc_size, &rd_trunc_cnt); sw_printf("The Read Persistent funtion returns value is %x \n \n", rdtest_truncated_retval); sw_printf("******TESTING:truncate persistent object*******\n"); if(rdtest_truncated_retval==1) { sw_printf("SUCCESS \n"); } else { sw_printf("FAILS \n"); } sw_printf("*****Reset the read object***** \n"); TEE_ResetTransientObject(*second_object); open_rename_retval=TEE_OpenPersistentObject(storageID,open_objectID, objectIDLen,rw_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_rename_retval); rename_ret_val=TEE_RenamePersistentObject(*second_object,rename_objectID, objectIDLen); sw_printf("The rename Persistent funtion returns value is %x \n \n", rename_ret_val); sw_printf("*****Reset the rename object***** \n"); TEE_ResetTransientObject(*second_object); optest_renamed_retval=TEE_OpenPersistentObject(storageID,rename_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",optest_renamed_retval); rdtest_renamed_retval=TEE_ReadObjectData(*second_object, (void*)&rd_rename_buffer,rd_rename_size, &rd_rename_cnt); sw_printf("The Read Persistent funtion returns value is %x \n \n", rdtest_renamed_retval); sw_printf("******TESTING:rename persistent object*******\n"); if(rdtest_renamed_retval==1) { sw_printf("SUCCESS \n"); } else { sw_printf("FAILS \n"); } sw_printf("*****Reset the read object***** \n"); TEE_ResetTransientObject(*second_object); open_seek_retval=TEE_OpenPersistentObject(storageID,seek_objectID, objectIDLen,rw_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",open_seek_retval); seek_ret_val=TEE_SeekObjectData(*second_object,offset,whence); sw_printf("The seek Persistent funtion returns value is %x \n \n", seek_ret_val); sw_printf("*****Reset the seek object***** \n"); TEE_ResetTransientObject(*second_object); open_delete_retval=TEE_OpenPersistentObject(storageID,delete_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion returns value is %x \n", open_delete_retval); TEE_CloseAndDeletePersistentObject(*second_object); sw_printf("*****Reset the close object***** \n"); TEE_ResetTransientObject(*second_object); optest_deleted_retval=TEE_OpenPersistentObject(storageID,delete_objectID, objectIDLen,r_flags,second_object); sw_printf("The open Persistent object funtion \ returns value is %x \n \n",optest_deleted_retval); sw_printf("******TESTING:close and delete persistent object*******\n"); if(optest_deleted_retval!=1) { sw_printf("SUCCESS \n"); } else { sw_printf("FAILS\n"); } sw_printf("*****Reset the seek object***** \n"); TEE_ResetTransientObject(*second_object); TEE_Attribute* attref; attref=(TEE_Attribute*)TEE_Malloc(sizeof(TEE_Attribute),0); TEE_InitRefAttribute(attref,0x00000001,p_buffer, (size_t)(sw_strlen((char*)p_buffer))); TEE_Free((void*)attref); TEE_Attribute* attval; attval=(TEE_Attribute*)TEE_Malloc(sizeof(TEE_Attribute),0); TEE_InitValueAttribute(attval,0x20000000,a_attribute_val,b_attribute_val); TEE_Free((void*)attval); TEE_Attribute attributes[3]; attributes[0].attributeID=0x20000000; attributes[0].content.value.a=0x0000000A; attributes[0].content.value.b=0x0000000B; attributes[1].attributeID=0x00000275; attributes[1].content.ref.length=(size_t)(sw_strlen((char*)attrsbuffer)); attributes[1].content.ref.buffer=TEE_Malloc (attributes[1].content.ref.length,0); TEE_MemCpy(attributes[1].content.ref.buffer,attrsbuffer, (u32)(attributes[1].content.ref.length)); attributes[2].attributeID=0x23425676; attributes[2].content.value.a=0x0000001E; attributes[2].content.value.b=0x0000001F; pop_ret_val=TEE_PopulateTransientObject(*second_object,attributes, attribute_cnt); sw_printf("the populate transient function returns value is %x \n", pop_ret_val); sw_printf("*****Reset the populate object***** \n"); TEE_ResetTransientObject(*second_object); TEE_CopyObjectAttributes(*second_object,*first_object); sw_printf("*****free the create object by call TEE_FreeTransientObject \ fn***** \n"); TEE_FreeTransientObject(*first_object); sw_printf("*****free the common object by call TEE_FreeTransientObject \ fn***** \n"); TEE_FreeTransientObject(*second_object); sw_printf("--------------Program Successfully Terminated--------------\n"); }
/** * @brief Test the mutex operations * * This function tests the functionality of mutex and semaphores * * @param req_buf: Virtual address of the request buffer * @param req_buf_len: Request buffer length * @param res_buf: Virtual address of the response buffer * @param res_buf_len: Response buffer length * @param meta_data: Virtual address of the meta data of the encoded data * @param ret_res_buf_len: Return length of the response buffer * * @return SMC return codes: * SMC_SUCCESS: API processed successfully. \n * SMC_*: An implementation-defined error code for any other error. */ int process_otz_mutex_test_cmd(void *req_buf, u32 req_buf_len, void *res_buf, u32 res_buf_len, struct otzc_encode_meta *meta_data, u32 *ret_res_buf_len) { otz_mutex_test_data_t otz_mutex_test_data; unsigned char *out_buf; int offset = 0, pos = 0, mapped = 0, type, out_len=0; while (offset <= req_buf_len) { if(decode_data(req_buf, meta_data, &type, &offset, &pos, &mapped, (void**)&out_buf, &out_len)) { return SMC_EINVAL_ARG; } if(type != OTZ_ENC_UINT32) { return SMC_EINVAL_ARG; } otz_mutex_test_data.len = *((u32*)out_buf); if(decode_data(req_buf, meta_data, &type, &offset, &pos, &mapped, (void**)&out_buf, &out_len)) { return SMC_EINVAL_ARG; } if(type != OTZ_ENC_ARRAY) { return SMC_EINVAL_ARG; } if(out_len < DATA_BUF_LEN) { sw_memcpy(otz_mutex_test_data.data, out_buf, out_len); } else { return(SMC_ENOMEM); } break; } #ifndef CONFIG_SW_ELF_LOADER_SUPPORT sw_printf("SW: Attempting to lock the variable \n"); #endif if(sw_mutex_lock(&g_otz_mutex) == OTZ_INVALID) { #ifndef CONFIG_SW_ELF_LOADER_SUPPORT sw_printf("SW: Unable to lock mutex. It is invalid \n"); #endif goto handle_error; } #ifndef CONFIG_SW_ELF_LOADER_SUPPORT sw_printf("SW: Lock successful. Trying to lock it one more time \n"); #endif if(sw_mutex_trylock(&g_otz_mutex) == OTZ_BUSY) { #ifndef CONFIG_SW_ELF_LOADER_SUPPORT sw_printf("SW: Mutex already locked. We cannot lock it anymore !! \n"); #endif } sw_mutex_unlock(&g_otz_mutex); #ifndef CONFIG_SW_ELF_LOADER_SUPPORT sw_printf("SW: Unlock successful. Trying to lock it one more time \n"); #endif if(sw_mutex_trylock(&g_otz_mutex) == OTZ_BUSY) { #ifndef CONFIG_SW_ELF_LOADER_SUPPORT sw_printf("SW: Error while unlocking the mutex !! \n"); #endif goto handle_error; } #ifndef CONFIG_SW_ELF_LOADER_SUPPORT sw_printf("SW: Going to sleep \n"); #endif usleep(10); #ifndef CONFIG_SW_ELF_LOADER_SUPPORT sw_printf("SW: Second time locking successful \n"); #endif sw_mutex_unlock(&g_otz_mutex); handle_error: offset = 0, pos = OTZ_MAX_REQ_PARAMS; while (offset <= res_buf_len) { if(decode_data(res_buf, meta_data, &type, &offset, &pos, &mapped, (void**)&out_buf, &out_len)) { return SMC_EINVAL_ARG; } if(type != OTZ_ENC_ARRAY) { return SMC_EINVAL_ARG; } if(out_len >= otz_mutex_test_data.len) { sw_memcpy(out_buf,otz_mutex_test_data.response, otz_mutex_test_data.len); if(update_response_len(meta_data, pos, otz_mutex_test_data.len)) { return SMC_EINVAL_ARG; } } else { return(SMC_ENOMEM); } break; } *ret_res_buf_len = otz_mutex_test_data.len; return 0; }
static int apply_relocations(void *file_map , Elf32_Shdr *sec_header , const char *str_tab, u32 symindex, u32 relindex, sa_config_t *conf, int *fl) { Elf32_Shdr *sym_sec = sec_header + symindex; Elf32_Shdr *rel_sec = sec_header + relindex; Elf32_Rel *rel = (Elf32_Rel *)rel_sec->sh_addr; Elf32_Sym *tmp_sym = NULL; Elf32_Sym *sym = (Elf32_Sym *)sym_sec->sh_addr; u32 i, status; char *entry_func= conf->entry_func; u32 symbol_addr,sym_index = symindex; s32 offset,loc_to_rel; Elf32_Shdr *dst_sec = sec_header + rel_sec->sh_info; Elf32_Ehdr *elf_header = NULL; const char *symname; Elf32_Shdr *tmp_shdr = sec_header; va_t * sym_tab_start = (va_t *)&_SW_KSYMTAB; va_t * sym_tab_end = (va_t *)&_SW_KSYMTAB_END; u32 n = ((u32)sym_tab_end - (u32)sym_tab_start) / sizeof(struct kernel_symbol); struct kernel_symbol *sym_tab = NULL; sym_tab=(struct kernel_symbol *)sym_tab_start; tmp_sym = sym; for(i=0; i < (rel_sec->sh_size)/(sizeof(Elf32_Rel)); i++){ /* Get the index inside the sym_tab */ offset = ELF32_R_SYM(rel[i].r_info); if(offset < 0 || offset > ((sym_sec->sh_size ) / (sizeof(Elf32_Sym)))){ sw_printf("Invalid offset inside the symbol table\n"); return -1; } /* Index of the symbol in the symbol table */ sym = (Elf32_Sym *)sym + offset; /* Note that st_name is a index into the symbol string table */ symname = str_tab + sym->st_name; if( (rel[i].r_offset < 0 || rel[i].r_offset > (dst_sec->sh_size - sizeof(u32)))){ sw_printf("Invalid offset of %s\n", symname); return -1; } switch(ELF32_R_TYPE(rel[i].r_info)) { case R_ARM_NONE: /* ignore it..*/ break; case R_ARM_ABS32: /* Right now we are just exporting functions, * add relocation support when we export global * variable too */ *(u32 *)loc_to_rel += sym->st_value; break; case R_ARM_CALL: case R_ARM_JUMP24: case R_ARM_PC24: /* Calculate relocations differently here, because there is a strong possibility * that the reloc offset will exceed 32MB , so assuming that we load @ address * closer to the kernel, use that address instead of dst_sec->sh_addr..Also we * are taking advantage of the fact that the .text section will be the first to * be mapped */ if(sym->st_shndx == SHN_UNDEF){ symbol_addr = get_undefined_symbol_addr( sym_tab,symname,n); if(symbol_addr == -1){ sw_printf("Unable to find" "symbol\n"); return -1; } loc_to_rel = (u32)(dst_sec->sh_addr + rel[i].r_offset); offset = (*(u32 *) loc_to_rel & 0x00ffffff) << 2; if(offset & 0x02000000) offset -= 0x04000000; /* We know that the .text section will be the first section to be mapped.. so * take advantage of it */ offset += symbol_addr - ((u32) BASE_LOAD_ADDRESS + rel[i].r_offset) ; if (offset & 3 || offset <= (s32)0xfe000000 || offset >= (s32)0x02000000) { sw_printf("Invalid \ relocation\n"); return -1; } offset >>= 2; /* we need only the last 24 bits */ *(u32 *)loc_to_rel &= 0xff000000; *(u32 *)loc_to_rel |= offset & 0x00ffffff; } else{
/** * @brief Dispatcher task entry point * * This task will process the smc commands and helps in creating * the service tasks and calls the service task functions. \n * 1. On arrival of API command invocation "valid params flag" got set. * Based on the flag, it process the command by invoking the appropriate task.\n * 2. At the completion of processing, the corresponding task sets the return * value of the command result in the dispatcher private data. * 3. Based on the result and the source, it returns to non-secure world or * originated task in case of IPI. * * @param cur_task_id - Dispatcher task identifier */ void dispatch_task(int cur_task_id) { int ret_val; int svc_id, task_id, cmd_id, cmd_type; sw_printf("SW: dispatch task id 0x%x\n", cur_task_id); invoke_ns_kernel(); while (1) { if(secure_interrupt_set) { secure_interrupt_set = 0; #ifdef CONFIG_EMULATE_FIQ emulate_timer_irq(); #endif return_secure_api(0); } else if(valid_params_flag && params_stack[0] == CALL_TRUSTZONE_API) { valid_params_flag = 0; get_api_context(&svc_id, &task_id, &cmd_id, &cmd_type); if((svc_id == OTZ_SVC_GLOBAL) && (cmd_id == OTZ_GLOBAL_CMD_ID_BOOT_ACK)) { if(cmd_type == OTZ_CMD_TYPE_NS_TO_SECURE) { tzhyp_boot_ack_event(); } set_secure_api_ret(0); } else if((svc_id == OTZ_SVC_GLOBAL) && (cmd_id == OTZ_GLOBAL_CMD_ID_OPEN_SESSION)) { if(cmd_type == OTZ_CMD_TYPE_NS_TO_SECURE) { /* sw_buddy_print_state(); */ ret_val = open_session_from_ns((void*)params_stack[1]); if(ret_val == OTZ_ENOMEM) set_secure_api_ret(SMC_ENOMEM); else if(ret_val == OTZ_EFAIL) set_secure_api_ret(SMC_ERROR); else set_secure_api_ret(0); } } else if((svc_id == OTZ_SVC_GLOBAL) && (cmd_id == OTZ_GLOBAL_CMD_ID_CLOSE_SESSION)) { if(cmd_type == OTZ_CMD_TYPE_NS_TO_SECURE) { ret_val = close_session_from_ns((void*)params_stack[1]); /* sw_buddy_print_state(); */ if(ret_val == OTZ_ENOMEM) set_secure_api_ret(SMC_ENOMEM); else if(ret_val == OTZ_EFAIL) set_secure_api_ret(SMC_ERROR); else set_secure_api_ret(0); } } #ifdef OTZONE_ASYNC_NOTIFY_SUPPORT else if((svc_id == OTZ_SVC_GLOBAL) && (cmd_id == OTZ_GLOBAL_CMD_ID_REGISTER_NOTIFY_MEMORY)) { if(cmd_type == OTZ_CMD_TYPE_NS_TO_SECURE) { ret_val = register_notify_data_api((void*)params_stack[1]); if(ret_val == OTZ_ENOMEM) set_secure_api_ret(SMC_ENOMEM); else if(ret_val == OTZ_EFAIL) set_secure_api_ret(SMC_ERROR); else set_secure_api_ret(0); } } else if((svc_id == OTZ_SVC_GLOBAL) && (cmd_id == OTZ_GLOBAL_CMD_ID_UNREGISTER_NOTIFY_MEMORY)) { if(cmd_type == OTZ_CMD_TYPE_NS_TO_SECURE) { ret_val = unregister_notify_data_api(); if(ret_val == OTZ_ENOMEM) set_secure_api_ret(SMC_ENOMEM); else if(ret_val == OTZ_EFAIL) set_secure_api_ret(SMC_ERROR); else set_secure_api_ret(0); } } else if((svc_id == OTZ_SVC_GLOBAL) && (cmd_id == OTZ_GLOBAL_CMD_ID_RESUME_ASYNC_TASK)) { if(cmd_type == OTZ_CMD_TYPE_NS_TO_SECURE) { if(task_id) resume_async_task(task_id); } } #endif else if(svc_id != OTZ_SVC_INVALID && task_id != 0 && cmd_id != OTZ_GLOBAL_CMD_ID_INVALID) { start_task(task_id, params_stack); } else { sw_printf("SW: Invalid service id 0x%x\n", svc_id); set_secure_api_ret(0); } } schedule(); if(g_dispatch_data->secure_api_set) { return_secure_api(g_dispatch_data->secure_api_ret_val); g_dispatch_data->secure_api_set = 0; } /* process_pending_task(); */ } }
/** * @brief * Function to open a specific file mentioned in the path * based on the incoming modes * @param file_path * Pointer to the location of the file path string * @param flags * Flags indicating the modes in which the file is to be opened * * @return Non-zero:File descriptor of the opened file Zero :File open is unsuccessful */ int file_open(const char *file_path,int flags) { const char *path = file_path; const char *temp_path,*delim_strt; char shrt_file_name[SHRT_FILE_NAME_LEN]; char long_file_name[LONG_FILE_NAME_LEN]; int len = 0,fl_des = 0,crt_flag,i; int delim_cnt = 0; int mode; int extn_len_cnt = 0; int seq_num = 1; bool is_file_found; dir_entry *entry = NULL; file_info *info; u8 *pwd = root_directory; u32 strt_cluster = rt_dir_strt_clus; bool is_long_file_name = false; sw_memset(long_file_name,SPACE_VAL,LONG_FILE_NAME_LEN); delim_cnt = find_depth(file_path); path = file_path; for(i=0;i<delim_cnt;i++){ if(*path == DELIMITER){ delim_strt = path; path++; } while((*path != EXTN_DELIMITER) && (*path != '\0') && (*path != DELIMITER) && (len < LONG_FILE_NAME_LEN)){ long_file_name[len] = *path; path++; len++; } temp_path = path; if(*temp_path == EXTN_DELIMITER){ temp_path++; while(*temp_path != DELIMITER && *temp_path != '\0'){ extn_len_cnt++; temp_path++; } } if(len > FILE_NAME_SHRT_LEN || extn_len_cnt > FILE_NAME_EXTN_LEN) is_long_file_name = true; if(is_long_file_name){ path = delim_strt; len = 0; if(*path == DELIMITER) path++; while(len < LONG_FILE_NAME_LEN && *path != '\0' && *path != DELIMITER){ long_file_name[len] = *path; path++; len++; } long_file_name[len] = '\0'; if(entry){ sw_free(entry); entry = NULL; } is_file_found = get_dir_entry(long_file_name,&entry, pwd,strt_cluster,true); } else{ len = FILE_NAME_SHRT_LEN; while(len < SHRT_FILE_NAME_LEN && *path != '\0' && *path != DELIMITER){ if(*path == EXTN_DELIMITER) path++; long_file_name[len] = *path; path++; len++; } convert_to_uppercase(long_file_name); if(entry){ sw_free(entry); entry = NULL; } is_file_found = get_dir_entry(long_file_name,&entry, pwd,strt_cluster,false); } if((is_file_found) & (i != delim_cnt - 1)){ strt_cluster = (entry->strt_clus_hword)<<16 | (entry->strt_clus_lword); pwd = cluster_to_memory_addr(strt_cluster); len = 0; extn_len_cnt = 0; sw_memset(shrt_file_name,SPACE_VAL,SHRT_FILE_NAME_LEN); sw_memset(long_file_name,SPACE_VAL,LONG_FILE_NAME_LEN); is_long_file_name = false; } } if(is_file_found){ if(flags & FILE_WRITE){ if(chk_file_lock(file_path) == -1) flags = FILE_READ; if(entry->attr & ATTR_READ){ sw_printf("Cannot open the file in write mode\n"); return -1; } } info = (file_info*)sw_malloc(sizeof(file_info)); fl_des = retrieve_file_info(info,entry,flags, dir_file_offset,file_path); } else{ if((flags & FILE_CREATE_NEW) || (flags & FILE_CREATE_ALWAYS) || (flags & FILE_WRITE)){ if(is_long_file_name){ get_short_file_name(long_file_name,shrt_file_name, (char)seq_num); if(get_dir_entry(shrt_file_name,NULL, pwd,strt_cluster,false) == true){ while(get_dir_entry(shrt_file_name,NULL, pwd,strt_cluster,false)){ seq_num++; get_short_file_name(long_file_name, shrt_file_name,'seq_num'); } } convert_to_uppercase(shrt_file_name); crt_flag = create_file(long_file_name, shrt_file_name,strt_cluster,&entry); } else crt_flag = create_file(NULL,long_file_name,strt_cluster,&entry); if(crt_flag == 0) sw_printf("File creation success\n"); info = (file_info*)sw_malloc(sizeof(file_info)); fl_des = retrieve_file_info(info,entry,flags, dir_file_offset,file_path); } else return -1; } return fl_des; }
/** * @brief */ static void sw_test_dev_close(void) { sw_printf("SW: TEST Device -1 close call\n"); return; }
/** * @brief */ static void sw_test_dev_open(void) { sw_printf("SW: TEST Device -1 open call\n"); return; }
/** * @brief Echo the data for the user supplied buffer with async support * * This function copies the request buffer to response buffer to show the * non-zero copy functionality and to show the async support by wait for the * flag and it got set in interrupt handler * * @param req_buf: Virtual address of the request buffer * @param req_buf_len: Request buffer length * @param res_buf: Virtual address of the response buffer * @param res_buf_len: Response buffer length * @param meta_data: Virtual address of the meta data of the encoded data * @param ret_res_buf_len: Return length of the response buffer * * @return SMC return codes: * SMC_SUCCESS: API processed successfully. \n * SMC_*: An implementation-defined error code for any other error. */ int process_otz_echo_async_send_cmd(void *req_buf, u32 req_buf_len, void *res_buf, u32 res_buf_len, struct otzc_encode_meta *meta_data, u32 *ret_res_buf_len) { echo_data_t echo_data; char *out_buf; int offset = 0, pos = 0, mapped = 0, type, out_len; int task_id; sw_tls *tls; struct echo_global *echo_global; task_id = get_current_task_id(); tls = get_task_tls(task_id); echo_global = (struct echo_global *)tls->private_data; if(!echo_global->data_available) { struct timer_event* tevent; timeval_t time; tevent = timer_event_create(&echo_task_handler,(void*)task_id); if(!tevent){ sw_printf("SW: Out of Memory : Cannot register Handler\n"); return SMC_ENOMEM; } /* Time duration = 100ms */ time.tval.nsec = 100000000; time.tval.sec = 0; struct sw_task* task = get_task(task_id); task->wq_head.elements_count = 0; INIT_LIST_HEAD(&task->wq_head.elements_list); task->wq_head.spin_lock.lock = 0; timer_event_start(tevent,&time); #ifdef ASYNC_DBG sw_printf("SW: Before calling wait event \n"); #endif sw_wait_event_async(&task->wq_head, echo_global->data_available, SMC_PENDING); #ifdef ASYNC_DBG sw_printf("SW: Coming out from wait event \n"); #endif } if(req_buf_len > 0) { while (offset <= req_buf_len) { if(decode_data(req_buf, meta_data, &type, &offset, &pos, &mapped, (void**)&out_buf, &out_len)) { return SMC_EINVAL_ARG; } else { if(type != OTZ_ENC_UINT32) return SMC_EINVAL_ARG; echo_data.len = *((u32*)out_buf); } if(decode_data(req_buf, meta_data, &type, &offset, &pos, &mapped, (void**)&out_buf, &out_len)) { return SMC_EINVAL_ARG; } else { if(type != OTZ_ENC_ARRAY) return SMC_EINVAL_ARG; sw_memcpy(echo_data.data, out_buf, echo_data.len); } break; } } offset = 0, pos = OTZ_MAX_REQ_PARAMS; if(res_buf_len > 0) { while (offset <= res_buf_len) { if(decode_data(res_buf, meta_data, &type, &offset, &pos, &mapped, (void**)&out_buf, &out_len)) { return SMC_EINVAL_ARG; } else { if(type != OTZ_ENC_ARRAY) return SMC_EINVAL_ARG; } sw_memcpy(out_buf, echo_data.data, echo_data.len); if(update_response_len(meta_data, pos, echo_data.len)) return SMC_EINVAL_ARG; break; } *ret_res_buf_len = echo_data.len; } /* sw_printf("SW: echo task data: %s\n", echo_data.data); */ /* sw_printf("SW: echo send cmd %s and len 0x%x strlen 0x%x\n", echo_data.data, echo_data.len, sw_strlen(echo_data.data)); */ return 0; }
/** * @brief * Function to write into the given file with the contents given * @param fd * File descriptor of the file * @param buffer * Pointer to the start of the contents which needs to be written into * the file * @param bytes_to_write * Indicates the number of bytes which needs to be written into the file * @return * Integer representing number of bytes successfully written into the file */ int file_write(int fd, const char *buffer,int bytes_to_write) { file_info *temp = file_head; u8 *file_cont; int tmp_offset = bytes_to_write; int alloc_cluster_cnt = 0; int bytes_to_copy; int bytes_written = 0; u32 new_cluster; u32 prev_cluster; while(temp != NULL){ if(temp->fd == fd) break; temp = temp->next; } if(temp->mode == FILE_READ){ sw_printf("File opened in read only mode\n"); return 0; } while(tmp_offset > 0){ if((temp->cur_cluster != 0) && (temp->cur_cluster != END_OF_CLUSTER) && (temp->cur_cluster != END_OF_ROOT_CLUSTER) && (cluster_size - temp->cur_offset != 0)) { file_cont = cluster_to_memory_addr(temp->cur_cluster) + temp->cur_offset; bytes_to_copy = cluster_size - (bytes_to_write - bytes_written); bytes_to_copy = bytes_to_copy > 0 ? bytes_to_write - bytes_written: cluster_size; bytes_to_copy = cluster_size - temp->cur_offset > bytes_to_copy ? bytes_to_copy : cluster_size - temp->cur_offset; sw_memcpy(file_cont,buffer + bytes_written,bytes_to_copy); bytes_written += bytes_to_copy; temp->cur_offset += bytes_to_copy; tmp_offset -= bytes_to_copy; prev_cluster = temp->cur_cluster; if(temp->cur_offset == cluster_size) temp->cur_cluster = get_fat_table_entry(temp->cur_cluster); if(temp->cur_cluster != 0 && temp->cur_cluster != END_OF_CLUSTER && temp->cur_cluster != END_OF_ROOT_CLUSTER && tmp_offset != 0) temp->cur_offset = 0; } else{ new_cluster = allocate_cluster(); if(alloc_cluster_cnt == 0 && temp->cur_cluster == 0 && temp->strt_cluster == 0){ temp->strt_cluster = new_cluster; *(u16*)(dir_file_offset + STRT_CLUS_LOW_OFF) = temp->strt_cluster & LOW_CLUSWORD_MASK; *(u16*)(dir_file_offset + STRT_CLUS_HIGH_OFF) = (temp->strt_cluster & HIGH_CLUSWORD_MASK) >> 16; } else write_fat_table(prev_cluster,new_cluster); temp->cur_cluster = new_cluster; temp->cur_offset = 0; alloc_cluster_cnt++; }
/** * @brief * Dummy wake up function. It is called from wakeup/wakeup function * @param wq * @param wakeup_flag */ void test_wq_dummy_wakeup_function(struct wait_queue* wq, u32 wakeup_flag) { sw_printf("SW: Inside Test Dummy wakeup function\n"); sw_default_wake_function(wq, wakeup_flag); }