/* * Create a new user process. * Params: * state->ebx - user address of name of executable * state->ecx - length of executable name * state->edx - user address of command string * state->esi - length of command string * Returns: pid of process if successful, error code (< 0) otherwise */ static int Sys_Spawn(struct Interrupt_State* state) { int retVal = -1; char *exeName = NULL; char *command = NULL; ulong_t exeNameLen = state->ecx + 1; /* +1 to add the 0 NULL later */ ulong_t commandLen = state->esi + 1; /* +1 to add the 0 NULL later */ struct Kernel_Thread* kthread = NULL; /* get some memory for the exe name and the args */ exeName = (char*) Malloc(exeNameLen); if (exeName == NULL) goto memfail; command = (char*) Malloc(commandLen); if (command == NULL) goto memfail; memset(exeName, '\0', exeNameLen); if(!Copy_From_User(exeName, state->ebx, exeNameLen)){ retVal = EUNSPECIFIED; goto fail; } memset(command, '\0', commandLen); if(!Copy_From_User(command, state->edx, commandLen)) { retVal = EUNSPECIFIED; goto fail; } Enable_Interrupts(); if ((retVal = Spawn(exeName, command, &kthread))) { goto fail; } Disable_Interrupts(); if (exeName!=NULL) Free(exeName); if (command!=NULL) Free(command); return kthread->pid; memfail: retVal = ENOMEM; fail: if(exeName) Free(exeName); if (command) Free(command); return retVal; }
/* * Open a file. * Params: * state->ebx - address of user string containing path of file to open * state->ecx - length of path * state->edx - file mode flags * * Returns: a file descriptor (>= 0) if successful, * or an error code (< 0) if unsuccessful */ static int Sys_Open(struct Interrupt_State *state) { char path[VFS_MAX_PATH_LEN] = {'\0', }; struct File **pFile; int fd; int rc; struct File** fileList = g_currentThread->userContext->fileList; for(fd = 0; fd < USER_MAX_FILES; fd++){ if(fileList[fd] == NULL){ pFile = &fileList[fd]; break; } } if(fd == USER_MAX_FILES) { return -1; } Copy_From_User(path, state->ebx, state->ecx); Enable_Interrupts(); if((rc = Open(path, state->edx, pFile)) < 0){ fd = rc; } Disable_Interrupts(); return fd; //TODO("Open system call"); }
/* * Create a semaphore. * Params: * state->ebx - user address of name of semaphore * state->ecx - length of semaphore name * state->edx - initial semaphore count * Returns: the global semaphore id */ static int Sys_CreateSemaphore(struct Interrupt_State* state) { char name[25]; Copy_From_User(name, state->ebx, state->ecx+1); return Create_Semaphore(name, state->edx); //TODO("CreateSemaphore system call"); }
/* "extern" to note that it's used by semaphore and networking system calls, defined in another file */ extern int Copy_User_String(ulong_t uaddr, ulong_t len, ulong_t maxLen, char **pStr) { int rc = 0; char *str; /* Ensure that string isn't too long. */ if (len > maxLen) return EINVALID; /* Allocate space for the string. */ str = (char *)Malloc(len + 1); if (str == 0) { rc = ENOMEM; goto done; } /* Copy data from user space. */ if (!Copy_From_User(str, uaddr, len)) { rc = EINVALID; Free(str); goto done; } str[len] = '\0'; /* Success! */ *pStr = str; done: return rc; }
/* * Mount a filesystem. * Params: * state->ebx - contains a pointer to the Mount_Syscall_Args structure * which contains the block device name, mount prefix, * and filesystem type * * Returns: * 0 if successful, error code if unsuccessful */ static int Sys_Mount(struct Interrupt_State *state) { int rc = 0; struct VFS_Mount_Request *args = 0; /* Allocate space for VFS_Mount_Request struct. */ if ((args = (struct VFS_Mount_Request *)Malloc(sizeof(struct VFS_Mount_Request))) == 0) { rc = ENOMEM; goto done; } /* Copy the mount arguments structure from user space. */ if (!Copy_From_User(args, state->ebx, sizeof(struct VFS_Mount_Request))) { rc = EINVALID; goto done; } /* * Hint: use devname, prefix, and fstype from the args structure * and invoke the Mount() VFS function. You will need to check * to make sure they are correctly nul-terminated. */ /* TODO("Mount system call"); */ Enable_Interrupts(); // duped from schulman // Print("eee %s %s %s\n", args->devname, args->prefix, args->fstype); rc = Mount(args->devname, args->prefix, args->fstype); Disable_Interrupts(); // duped from schulman done: if (args != 0) Free(args); return rc; }
/* * Open a directory. * Params: * state->ebx - address of user string containing path of directory to open * state->ecx - length of path * * Returns: a file descriptor (>= 0) if successful, * or an error code (< 0) if unsuccessful */ static int Sys_OpenDirectory(struct Interrupt_State *state) { char path[VFS_MAX_PATH_LEN] = {'\0' }; struct File **pDir; /* important */ int fd; int rc; struct File** fileList = g_currentThread->userContext->fileList; for(fd = 0; fd < USER_MAX_FILES; fd++){ if(fileList[fd] == NULL){ pDir = &fileList[fd]; break; } } if(fd == USER_MAX_FILES) { return -1; } Copy_From_User(path, state->ebx, state->ecx); Enable_Interrupts(); //Print("Sys_OpenDirectory : %s\n", path); if((rc = Open_Directory(path, pDir)) < 0){ /* important */ fd = rc; } //Print("%d, fileList[fd] : %x\n", fd, fileList[fd]); Disable_Interrupts(); return fd; //TODO("Open directory system call"); }
/* * Create a new user process. * Params: * state->ebx - user address of name of executable * state->ecx - length of executable name * state->edx - user address of command string * state->esi - length of command string * state->edi - whether background or foreground * Returns: pid of process if successful, error code (< 0) otherwise */ static int Sys_Spawn(struct Interrupt_State* state) { char program[256] = {'\0',}; char command[256] = {'\0',}; int pid; struct Kernel_Thread **pThread; Copy_From_User(program, state->ebx, state->ecx); Copy_From_User(command, state->edx, state->esi); //Print("%s\n", program); //Print("%s\n", command); Enable_Interrupts(); pid = Spawn(program, command, pThread, state->edi); Disable_Interrupts(); return pid; //TODO("Spawn system call"); }
/* * Format a device * Params: * state->ebx - address of user string containing device to format * state->ecx - length of device name string * state->edx - address of user string containing filesystem type * state->esi - length of filesystem type string * Returns: 0 if successful, error code (< 0) if unsuccessful */ static int Sys_Format(struct Interrupt_State *state) { char devname[BLOCKDEV_MAX_NAME_LEN] = {'\0', }; char fstype[VFS_MAX_FS_NAME_LEN] = {'\0', }; int rc = 0; if (!Copy_From_User(devname, state->ebx, state->ecx)) return EINVALID; if (!Copy_From_User(fstype, state->edx, state->esi)) return EINVALID; Enable_Interrupts(); rc = Format(devname, fstype); Disable_Interrupts(); //TODO("Format system call"); return rc; }
/* * Print a string to the console. * Params: * state->ebx - user pointer of string to be printed * state->ecx - number of characters to print * Returns: 0 if successful, -1 if not */ static int Sys_PrintString(struct Interrupt_State* state) { char string[100] = {'\0',}; int len = state->ecx; int i; Copy_From_User(string, state->ebx, len); Print(string); return 0; }
/* * Get file metadata. * Params: * state->ebx - address of user string containing path of file * state->ecx - length of path * state->edx - user address of struct VFS_File_Stat object to store metadata in * * Returns: 0 if successful, error code (< 0) if unsuccessful */ static int Sys_Stat(struct Interrupt_State *state) { char path[VFS_MAX_PATH_LEN] = {'\0', }; int rc = 0; Copy_From_User(path, state->ebx, state->ecx); Enable_Interrupts(); rc = Stat(path, (struct VFS_File_Stat *)(USER_BASE_ADDR + state->edx)); /* weak */ Disable_Interrupts(); return rc; //TODO("Stat system call"); }
/* * Print a string to the console. * Params: * state->ebx - user pointer of string to be printed * state->ecx - number of characters to print * Returns: 0 if successful, -1 if not */ static int Sys_PrintString(struct Interrupt_State* state) { int length=state->ecx; char *buffer=(char*)Malloc(length); if(Copy_From_User(buffer,state->ebx,length)) { Put_Buf(buffer,length); return 0; } return -1; }
/* * Create directory * Params: * state->ebx - address of user string containing path of new directory * state->ecx - length of path * * Returns: 0 if successful, error code (< 0) if unsuccessful */ static int Sys_CreateDir(struct Interrupt_State *state) { char path[VFS_MAX_PATH_LEN] = {'\0', }; int rc; Copy_From_User(path, state->ebx, state->ecx); Enable_Interrupts(); if((rc = Create_Directory(path)) < 0){ ; } Disable_Interrupts(); return rc; //TODO("CreateDir system call"); }
/* * Create a new user process. * Params: * state->ebx - user address of name of executable * state->ecx - length of executable name * state->edx - user address of command string * state->esi - length of command string * Returns: pid of process if successful, error code (< 0) otherwise */ static int Sys_Spawn(struct Interrupt_State* state) { int programLength= (int)state->ecx; int commandLength=(int)state->esi; char *program=(char*)Malloc(programLength + 1); char *command=(char*)Malloc(commandLength + 1); if(program==NULL || command==NULL) return -1; if(!Copy_From_User(program,(ulong_t)state->ebx,programLength) || !Copy_From_User(command,(ulong_t)state->edx,(ulong_t)commandLength)) return -1; program[programLength]='\0'; command[commandLength]='\0'; struct Kernel_Thread *kthread; Enable_Interrupts (); int pid = Spawn(program,command,&kthread); Disable_Interrupts(); return pid; }
/* * Delete a file. * Params: * state->ebx - address of user string containing path to delete * state->ecx - length of path * * Returns: 0 if successful, error code (< 0) if unsuccessful */ static int Sys_Delete(struct Interrupt_State *state) { char path[VFS_MAX_PATH_LEN] = {'\0' }; int rc; Copy_From_User(path, state->ebx, state->ecx); Enable_Interrupts(); if((rc = Delete(path)) < 0){ ; } Disable_Interrupts(); return rc; //TODO("Delete system call"); }
static int get_path_from_registers(uint_t addr, uint_t length, char **pPath) { if(length > 1024) { return ENAMETOOLONG; } *pPath = Malloc(length + 1); if(!*pPath) { return ENOMEM; } if (!Copy_From_User(*pPath, addr, length)) { Free(*pPath); return EINVALID; } (*pPath)[length] = '\0'; return 0; }
/* * Print a string to the console. * Params: * state->ebx - user pointer of string to be printed * state->ecx - number of characters to print * Returns: 0 if successful, -1 if not */ static int Sys_PrintString(struct Interrupt_State* state) { char *message = NULL; ulong_t len = state->ecx; if (len > 1024){ return -1; } message = Malloc(sizeof(char) * len + 1); if (message == NULL) { return -1; } if (!Copy_From_User(message, state->ebx, len)) { Free(message); return -1; } Put_Buf(message, len); Free(message); return 0; }
static int s3c_mfc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; MFCInstCtx *pMfcInst; MFC_HANDLE *handle; unsigned char *OutBuf = NULL; MFC_CODECMODE codec_mode = 0; int buf_size; unsigned int tmp; MFC_ARGS args; enc_info_t enc_info; // modified by RainAde for header type of mpeg4 (+ VOS/VO) #if 1 // Hdr0 : SPS or VOL // Hdr1 : PPS or VOS // Hdr2 : VO (VIS) int nStrmLen, nHdrLen, nHdr0Len, nHdr1Len, nHdr2Len; #else // modified by RainAde for composer interface int nStrmLen, nHdrLen, nSps, nPps; #endif void *temp; unsigned int vir_mv_addr; unsigned int vir_mb_type_addr; ////////////////////// // Parameter Check // ////////////////////// handle = (MFC_HANDLE *)file->private_data; if (handle->mfc_inst == NULL) { return -EFAULT; } pMfcInst = handle->mfc_inst; switch(cmd) { case IOCTL_MFC_MPEG4_ENC_INIT: case IOCTL_MFC_H264_ENC_INIT: case IOCTL_MFC_H263_ENC_INIT: MFC_Mutex_Lock(); LOG_MSG(LOG_TRACE, "mfc_ioctl", "cmd = %d\r\n", cmd); Copy_From_User(&args.enc_init, (MFC_ENC_INIT_ARG *)arg, sizeof(MFC_ENC_INIT_ARG)); if ( cmd == IOCTL_MFC_MPEG4_ENC_INIT ) codec_mode = MP4_ENC; else if ( cmd == IOCTL_MFC_H264_ENC_INIT ) codec_mode = AVC_ENC; else if ( cmd == IOCTL_MFC_H263_ENC_INIT ) codec_mode = H263_ENC; ////////////////////////////// // Initialize MFC Instance // ////////////////////////////// enc_info.width = args.enc_init.in_width; enc_info.height = args.enc_init.in_height; enc_info.bitrate = args.enc_init.in_bitrate; enc_info.gopNum = args.enc_init.in_gopNum; enc_info.frameRateRes = args.enc_init.in_frameRateRes; enc_info.frameRateDiv = args.enc_init.in_frameRateDiv; ret = MFCInst_Enc_Init(pMfcInst, codec_mode, &enc_info); args.enc_init.ret_code = ret; Copy_To_User((MFC_ENC_INIT_ARG *)arg, &args.enc_init, sizeof(MFC_ENC_INIT_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_ENC_EXE: case IOCTL_MFC_H264_ENC_EXE: case IOCTL_MFC_H263_ENC_EXE: MFC_Mutex_Lock(); Copy_From_User(&args.enc_exe, (MFC_ENC_EXE_ARG *)arg, sizeof(MFC_ENC_EXE_ARG)); tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; // from 2.8.5 //dmac_clean_range(pMfcInst->pFramBuf, pMfcInst->pFramBuf + tmp); //outer_clean_range(__pa(pMfcInst->pFramBuf), __pa(pMfcInst->pFramBuf + tmp)); // from 2.8.5 : cache flush cpu_cache.flush_kern_all(); ////////////////////////// // Decode MFC Instance // ////////////////////////// // modified by RainAde for composer interface //ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen, &nHdr0Len, &nHdr1Len); // modified by RainAde for header type of mpeg4 (+ VOS/VO) ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen, &nHdr0Len, &nHdr1Len, &nHdr2Len); // from 2.8.5 //dmac_clean_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); //outer_clean_range(__pa(pMfcInst->pStrmBuf), __pa(pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE)); args.enc_exe.ret_code = ret; if (ret == MFCINST_RET_OK) { args.enc_exe.out_encoded_size = nStrmLen; args.enc_exe.out_header_size = nHdrLen; // modified by RainAde for composer interface args.enc_exe.out_header0_size = nHdr0Len; args.enc_exe.out_header1_size = nHdr1Len; // modified by RainAde for header type of mpeg4 (+ VOS/VO) args.enc_exe.out_header2_size = nHdr2Len; } Copy_To_User((MFC_ENC_EXE_ARG *)arg, &args.enc_exe, sizeof(MFC_ENC_EXE_ARG)); // added by RainAde for cache coherency cpu_cache.dma_inv_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_DEC_INIT: case IOCTL_MFC_H264_DEC_INIT: case IOCTL_MFC_H263_DEC_INIT: case IOCTL_MFC_VC1_DEC_INIT: MFC_Mutex_Lock(); #ifdef CONFIG_MACH_SATURN lcd_gamma_change(LCD_VIDEO); // when decoder init to start playing video, AMOLED gamma set to video mode #endif Copy_From_User(&args.dec_init, (MFC_DEC_INIT_ARG *)arg, sizeof(MFC_DEC_INIT_ARG)); // yj: fix the PiP problem cpu_cache.flush_kern_all(); if ( cmd == IOCTL_MFC_MPEG4_DEC_INIT ) codec_mode = MP4_DEC; else if ( cmd == IOCTL_MFC_H264_DEC_INIT ) codec_mode = AVC_DEC; else if ( cmd == IOCTL_MFC_H263_DEC_INIT) codec_mode = H263_DEC; else { codec_mode = VC1_DEC; } ////////////////////////////// // Initialize MFC Instance // ////////////////////////////// ret = MFCInst_Init(pMfcInst, codec_mode, args.dec_init.in_strmSize); args.dec_init.ret_code = ret; if (ret == MFCINST_RET_OK) { args.dec_init.out_width = pMfcInst->width; args.dec_init.out_height = pMfcInst->height; args.dec_init.out_buf_width = pMfcInst->buf_width; args.dec_init.out_buf_height = pMfcInst->buf_height; } Copy_To_User((MFC_DEC_INIT_ARG *)arg, &args.dec_init, sizeof(MFC_DEC_INIT_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_MPEG4_DEC_EXE: case IOCTL_MFC_H264_DEC_EXE: case IOCTL_MFC_H263_DEC_EXE: case IOCTL_MFC_VC1_DEC_EXE: MFC_Mutex_Lock(); Copy_From_User(&args.dec_exe, (MFC_DEC_EXE_ARG *)arg, sizeof(MFC_DEC_EXE_ARG)); // from 2.8.5 //dmac_clean_range(pMfcInst->pStrmBuf, pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE); //outer_clean_range(__pa(pMfcInst->pStrmBuf), __pa(pMfcInst->pStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE)); // from 2.8.5 : cache flush cpu_cache.flush_kern_all(); if (pMfcInst->inbuf_type == DEC_INBUF_LINE_BUF) { ret = MFCInst_Decode(pMfcInst, args.dec_exe.in_strmSize); } else if (pMfcInst->inbuf_type == DEC_INBUF_RING_BUF) { ret = MFCInst_Decode_Stream(pMfcInst, args.dec_exe.in_strmSize); } else { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "Buffer type is not defined.\n"); MFC_Mutex_Release(); args.dec_exe.ret_code = -1; return -EINVAL; } args.dec_exe.ret_code = ret; Copy_To_User((MFC_DEC_EXE_ARG *)arg, &args.dec_exe, sizeof(MFC_DEC_EXE_ARG)); // added by RainAde for cache coherency tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; cpu_cache.dma_inv_range(pMfcInst->pFramBuf, pMfcInst->pFramBuf + tmp); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_RING_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); ret = MFCInst_GetRingBuf(pMfcInst, &OutBuf, &buf_size); args.get_buf_addr.out_buf_size = buf_size; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + ((int)(OutBuf - GetDataBufVirAddr())); args.get_buf_addr.ret_code = ret; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_LINE_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); ret = MFCInst_GetLineBuf(pMfcInst, &OutBuf, &buf_size); args.get_buf_addr.out_buf_size = buf_size; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + (OutBuf - GetDataBufVirAddr()); args.get_buf_addr.ret_code = ret; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_DBK_BUF_ADDR: // newly added by yj: returns to DBK_BUF' virtual address and its size. MFC_Mutex_Lock(); Copy_From_User(&args.get_dbkbuf_addr, (MFC_GET_DBK_BUF_ARG *)arg, sizeof(MFC_GET_DBK_BUF_ARG)); if (pMfcInst->isMp4DbkOn != 1) { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "MFC DBK_BUF is not internally allocated yet.\n"); MFC_Mutex_Release(); return -EFAULT; } args.get_dbkbuf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; args.get_dbkbuf_addr.out_buf_addr = args.get_dbkbuf_addr.in_usr_mapped_addr + ((unsigned int)GetDbkBufVirAddr() - (unsigned int)GetDataBufVirAddr()); args.get_dbkbuf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_DBK_BUF_ARG *)arg, &args.get_dbkbuf_addr, sizeof(MFC_GET_DBK_BUF_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_FRAM_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); if (pMfcInst->pFramBuf == NULL) { LOG_MSG(LOG_ERROR, "s3c_mfc_ioctl", "MFC Frame buffer is not internally allocated yet.\n"); MFC_Mutex_Release(); return -EFAULT; } // FRAM_BUF address is calculated differently for Encoder and Decoder. switch (pMfcInst->codec_mode) { case MP4_DEC: case AVC_DEC: case VC1_DEC: case H263_DEC: // Decoder case args.get_buf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; tmp = (unsigned int)args.get_buf_addr.in_usr_data + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->idx) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); #if (MFC_ROTATE_ENABLE == 1) if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) ) { tmp = (unsigned int)args.get_buf_addr.in_usr_data + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->frambufCnt) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); } #endif args.get_buf_addr.out_buf_addr = tmp; break; case MP4_ENC: case AVC_ENC: case H263_ENC: // Encoder case tmp = (pMfcInst->width * pMfcInst->height * 3) >> 1; args.get_buf_addr.out_buf_addr = args.get_buf_addr.in_usr_data + (pMfcInst->idx * tmp) + (int)(pMfcInst->pFramBuf - GetDataBufVirAddr()); break; } args.get_buf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR: MFC_Mutex_Lock(); Copy_From_User(&args.get_buf_addr, (MFC_GET_BUF_ADDR_ARG *)arg, sizeof(MFC_GET_BUF_ADDR_ARG)); args.get_buf_addr.out_buf_size = (pMfcInst->buf_width * pMfcInst->buf_height * 3) >> 1; // args.get_buf_addr.out_buf_size = ((pMfcInst->width+2*DIVX_PADDING) * (pMfcInst->height+2*DIVX_PADDING) * 3) >> 1; tmp = (unsigned int)S3C6400_BASEADDR_MFC_DATA_BUF + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->idx) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); //.[ i: sichoi 081103 (ROTATE) #if (MFC_ROTATE_ENABLE == 1) if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) ) { tmp = (unsigned int)S3C6400_BASEADDR_MFC_DATA_BUF + ( ((unsigned int) pMfcInst->pFramBuf) \ + (pMfcInst->frambufCnt) * (args.get_buf_addr.out_buf_size + ZERO_COPY_HDR_SIZE) - (unsigned int)GetDataBufVirAddr() ); } #endif //.] sichoi 081103 args.get_buf_addr.out_buf_addr = tmp; args.get_buf_addr.ret_code = MFCINST_RET_OK; Copy_To_User((MFC_GET_BUF_ADDR_ARG *)arg, &args.get_buf_addr, sizeof(MFC_GET_BUF_ADDR_ARG)); MFC_Mutex_Release(); break; case IOCTL_MFC_GET_MPEG4_ASP_PARAM: #if (defined(DIVX_ENABLE) && (DIVX_ENABLE == 1)) Copy_From_User(&args.mpeg4_asp_param, (MFC_GET_MPEG4ASP_ARG *)arg, sizeof(MFC_GET_MPEG4ASP_ARG)); ret = MFCINST_RET_OK; args.mpeg4_asp_param.ret_code = MFCINST_RET_OK; args.mpeg4_asp_param.mp4asp_vop_time_res = pMfcInst->RET_DEC_SEQ_INIT_BAK_MP4ASP_VOP_TIME_RES; args.mpeg4_asp_param.byte_consumed = pMfcInst->RET_DEC_PIC_RUN_BAK_BYTE_CONSUMED; args.mpeg4_asp_param.mp4asp_fcode = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_FCODE; args.mpeg4_asp_param.mp4asp_time_base_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_TIME_BASE_LAST; args.mpeg4_asp_param.mp4asp_nonb_time_last = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_NONB_TIME_LAST; args.mpeg4_asp_param.mp4asp_trd = pMfcInst->RET_DEC_PIC_RUN_BAK_MP4ASP_MP4ASP_TRD; args.mpeg4_asp_param.mv_addr = (args.mpeg4_asp_param.in_usr_mapped_addr + MFC_STRM_BUF_SIZE) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf); args.mpeg4_asp_param.mb_type_addr = args.mpeg4_asp_param.mv_addr + 25920; args.mpeg4_asp_param.mv_size = 25920; args.mpeg4_asp_param.mb_type_size = 1620; vir_mv_addr = (unsigned int)((pMfcInst->pStrmBuf + MFC_STRM_BUF_SIZE) + (pMfcInst->mv_mbyte_addr - pMfcInst->phyadrFramBuf)); vir_mb_type_addr = vir_mv_addr + 25920; Copy_To_User((MFC_GET_MPEG4ASP_ARG *)arg, &args.mpeg4_asp_param, sizeof(MFC_GET_MPEG4ASP_ARG)); // from 2.8.5 //dmac_clean_range(vir_mv_addr, vir_mv_addr + args.mpeg4_asp_param.mv_size); //outer_clean_range(__pa(vir_mv_addr), __pa(vir_mv_addr + args.mpeg4_asp_param.mv_size)); //dmac_clean_range(vir_mb_type_addr, vir_mb_type_addr + args.mpeg4_asp_param.mb_type_size); //outer_clean_range(__pa(vir_mb_type_addr), __pa(vir_mb_type_addr + args.mpeg4_asp_param.mb_type_size)); #endif break; case IOCTL_MFC_GET_CONFIG: MFC_Mutex_Lock(); Copy_From_User(&args, (MFC_ARGS *)arg, sizeof(MFC_ARGS)); ret = MFC_GetConfigParams(pMfcInst, &args); Copy_To_User((MFC_ARGS *)arg, &args, sizeof(MFC_ARGS)); MFC_Mutex_Release(); break; case IOCTL_MFC_SET_CONFIG: MFC_Mutex_Lock(); Copy_From_User(&args, (MFC_ARGS *)arg, sizeof(MFC_ARGS)); ret = MFC_SetConfigParams(pMfcInst, &args); Copy_To_User((MFC_ARGS *)arg, &args, sizeof(MFC_ARGS)); MFC_Mutex_Release(); break; case IOCTL_MFC_SET_H263_MULTIPLE_SLICE: MFC_Mutex_Lock(); pMfcInst->multiple_slice = 1; MFC_Mutex_Release(); break; case IOCTL_VIRT_TO_PHYS: //MFC_Mutex_Lock(); temp = __virt_to_phys((void *)arg); return (int)temp; //MFC_Mutex_Release(); break; default: MFC_Mutex_Lock(); LOG_MSG(LOG_TRACE, "s3c_mfc_ioctl", "Requested ioctl command is not defined. (ioctl cmd=0x%X)\n", cmd); MFC_Mutex_Release(); return -EINVAL; } switch(ret) { case MFCINST_RET_OK: return TRUE; default: return -1; } return -1; }
static int Sys_Spawn( struct Interrupt_State* state ) { int i; int ret; int argc; char *argv[MAX_ARGS]; struct Kernel_Thread *thread; struct User_Program *programPtr; const void* userPtr = (const void*) state->ebx; unsigned int length = state->ecx; unsigned char* buf; // Make sure buf is a reasonable size. if ( length > 1024 ) return -1; buf = Malloc_Atomic( length + 1 ); if ( buf == 0 ) return -1; if ( !Copy_From_User( buf, userPtr, length ) ) { Free_Atomic( buf ); return -1; } buf[ length ] = '\0'; // convert buf to argc and argv; i = 0; argc = 0; argv[0] = buf; while (i < 1024 && buf[i]) { if (buf[i] == ' ') { buf[i] = '\0'; i++; // skip sequence of white space while (i < 1024 && buf[i] == ' ') i++; if (i < 1024) { ++argc; if (argc == MAX_ARGS) return -1; argv[argc] = &buf[i]; } } else { i++; } } argc++; programPtr = loadElfProgram(argv[0]); if (programPtr) { ret = thread->pid; // setup argc and argv thread = Start_User_Program(programPtr, FALSE, argc, argv, buf, length); ret = thread->pid; if (programPtr->program) { Free_Atomic( (char *) programPtr->executable ); } } else { thread = 0; ret = -1; } KASSERT( Interrupts_Enabled() ); return ret; }