Example #1
0
/*
 * 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;
}
Example #2
0
/*
 * 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");
}
Example #3
0
/*
 * 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");
}
Example #4
0
/* "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;
}
Example #5
0
/*
 * 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;
}
Example #6
0
/*
 * 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");
}
Example #7
0
/*
 * 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");
}
Example #8
0
/*
 * 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;
}
Example #9
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 string[100] = {'\0',};
	int len = state->ecx;	
	int i;

	Copy_From_User(string, state->ebx, len);
 	Print(string);
 	return 0;
}
Example #10
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");
}
Example #11
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)
{
	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;
}
Example #12
0
/*
 * 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");
}
Example #13
0
/*
 * 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;
}
Example #14
0
/*
 * 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");
}
Example #15
0
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;
}
Example #16
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;
}
Example #17
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;
}
Example #18
0
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;
}