/* Read count bytes (or less) from fd into the buffer buf. */ ssize_t read_syscall(int fd, void *buf, size_t count) { // Check for invalid memory range or file descriptors if (check_mem((char *) buf, (int) count, SDRAM_START, SDRAM_END) == false) { invalid_syscall(-EFAULT); } else if (fd != STDIN_FILENO) { invalid_syscall(-EBADF); } size_t i = 0; char *buffer = (char *) buf; char read_char; while (i < count) { read_char = getc(); if (read_char == 4) { //EOT character return i; } else if (((read_char == 8) || (read_char == 127))) { // backspace or DEL character buffer[i] = 0; // '\0' character if(i > 0) { i--; puts("\b \b"); } } else if ((read_char == 10) || (read_char == 13)) { // '\n' newline or '\r' carriage return character buffer[i] = '\n'; putc('\n'); return (i+1); } else { // put character into buffer and putc buffer[i] = read_char; i++; putc(read_char); } } return i; }
/* * implementation of the C_SWI_Handler * @param: swi_num- swi number * @param: sp- stack pointer that points to block of user registers * @return: return value form swi on success, -1 on failure (swi num not supported) */ void C_SWI_Handler(int swi_num, unsigned int *sp) { unsigned int r0, r1, r2; switch(swi_num) { case READ_SWI: enable_interrupts(); r0 = *sp; r1 = *(sp + 1); r2 = *(sp + 2); *sp = read_syscall((int)r0, (void *)r1, (size_t)r2); break; case WRITE_SWI: enable_interrupts(); r0 = *sp; r1 = *(sp + 1); r2 = *(sp + 2); *sp = write_syscall((int)r0, (const void *)r1, (size_t)r2); break; case TIME_SWI: enable_interrupts(); *sp = time_syscall(); break; case SLEEP_SWI: // enable_interrupts(); r0 = *sp; sleep_syscall((unsigned long)r0); break; case CREATE_SWI: r0 = *sp; r1 = *(sp + 1); *sp = task_create((task_t *)r0, (size_t)r1); break; case EVENT_WAIT: printf("calling event_wait sp is %p\n", sp); r0 = *sp; *sp = event_wait((unsigned int)r0); // while(1); printf("returned from event_wait\n"); break; case MUTEX_CREATE: *sp = mutex_create(); break; case MUTEX_LOCK: r0 = *sp; *sp = mutex_lock((int)r0); break; case MUTEX_UNLOCK: r0 = *sp; *sp = mutex_unlock((int)r0); break; default: printf("\n C_SWI_Handler:invalid SWI call, panic\n"); invalid_syscall(swi_num); } return; }
//call the appropriate method based on the swi int c_swi_handler(unsigned swi_num, unsigned * regs){ int ret = 0; //if(debug_enabled ==1) printf ("c_swi_handler:: swi_num = %d\n", swi_num ) ; switch(swi_num){ case EXIT_SWI: c_exit(regs[0]); break; case READ_SWI: ret = read_syscall(regs[0], (void *) regs[1], regs[2]); break; case WRITE_SWI: ret = write_syscall(regs[0], (void *) regs[1], regs[2]); break; case TIME_SWI: ret = time_syscall(); break; case SLEEP_SWI: sleep_syscall(regs[0]); break; case CREATE_SWI: ret = task_create((task_t*)regs[0], regs[1]); break; case MUTEX_CREATE: ret = mutex_create(); break; case MUTEX_LOCK: ret = mutex_lock(regs[0]); break; case MUTEX_UNLOCK: ret = mutex_unlock(regs[0]); break; case EVENT_WAIT: ret = event_wait(regs[0]); break; default: invalid_syscall(0x0badc0de); break; } return ret; }
/* Write count bytes to fd from the buffer buf. */ ssize_t write_syscall(int fd, const void *buf, size_t count) { // Check for invalid memory range or file descriptors if (check_mem((char *) buf, (int) count, SDRAM_START, SDRAM_END) == false && check_mem((char *) buf, (int) count, SFROM_START, SFROM_END) == false) { invalid_syscall(-EFAULT); } else if (fd != STDOUT_FILENO) { invalid_syscall(-EBADF); } char *buffer = (char *) buf; size_t i; char read_char; for (i = 0; i < count; i++) { // put character into buffer and putc read_char = buffer[i]; putc(read_char); } return i; }
/* Called by assembly Swi_Handler, with a swi number and a pointer to * register values on the stack. * requires valid swi_Num, this check is done in kernel. * returns a return value, depending on which swi_handler was called. */ int C_SWI_Handler(int swi_Num, unsigned int *regs) { switch( swi_Num ) { case READ_SWI: return read_syscall((int)regs[0], (char *)regs[1], (size_t)regs[2]); case WRITE_SWI: return write_syscall((int)regs[0], (char *)regs[1], (size_t)regs[2]); case TIME_SWI: return time_syscall(); case SLEEP_SWI: sleep_syscall((unsigned long)regs[0]); return 0; case CREATE_SWI: return task_create((task_t *)regs[0], (size_t)regs[1]); case MUTEX_CREATE: return mutex_create(); case MUTEX_LOCK: return mutex_lock((int)regs[0]); case MUTEX_UNLOCK: return mutex_unlock((int)regs[0]); case EVENT_WAIT: return event_wait((unsigned int)regs[0]); default: invalid_syscall(swi_Num); } assert(0); //Should not reach here return(0); }
/* ------------------------------------------------ Function: C_SWI_Handler Description: The SWI handler is called by the S_Handler assembly code. Blocking interrupts for tasks related to context switching/premption. Input arguments: unsigned swi_num - Extracted SWI number from original SWI call. unsigned *regs - Location of saved arguments from the caller. ------------------------------------------------ */ void C_SWI_Handler(unsigned swi_num, unsigned *regs){ switch(swi_num){ case READ_SWI: read(regs); break; case WRITE_SWI: write(regs); break; case TIME_SWI: time_swi(regs); break; case SLEEP_SWI: sleep_swi(*((unsigned long *)regs)); break; case CREATE_SWI: disable_interrupts(); regs[0] = task_create((task_t*) regs[0], (size_t)regs[1]); break; case EVENT_WAIT: disable_interrupts(); regs[0] = event_wait((unsigned int) regs[0]); break; case MUTEX_CREATE: disable_interrupts(); regs[0] = mutex_create(); break; case MUTEX_LOCK: disable_interrupts(); regs[0] = mutex_lock(*(int*)regs); break; case MUTEX_UNLOCK: disable_interrupts(); regs[0] = mutex_unlock(*(int*)regs); break; default: regs[0] = BADCODE; invalid_syscall(swi_num); break; } }
void C_SWI_Handler(unsigned swi_num, unsigned *regs){ unsigned *value; value=regs; switch (swi_num) { case READ_SWI: *value= read_syscall(regs[0],(void *)regs[1],regs[2]); break; case WRITE_SWI: *value=write_syscall(regs[0],(void *)regs[1],regs[2]); break; case TIME_SWI: *value=time_syscall(); break; case SLEEP_SWI: sleep_syscall(regs[0]); break; case CREATE_SWI: task_create((task_t *)regs[0],regs[1]); break; case MUTEX_CREATE: *value=mutex_create(); break; case MUTEX_LOCK: *value=mutex_lock(regs[0]); break; case MUTEX_UNLOCK: *value=mutex_unlock(regs[0]); break; case EVENT_WAIT: event_wait(regs[0]); break; default: invalid_syscall(swi_num); } /* end switch */ return; }