⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dld_server.c

📁 Omap5910 上实现双核通信 DSP GateWay
💻 C
📖 第 1 页 / 共 2 页
字号:
	return 0;}static int server_dspunconfig(int fd){	int cfd;	int n_task;	int status = 0;	if ((cfd = open(DEVNAME_CONTROL, O_RDWR)) < 0) {		prmsg("%s open failed at %s line %d\n",		      DEVNAME_CONTROL, __FILE__, __LINE__);		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	if ((n_task = ioctl(fd, OMAP_DSP_IOCTL_TASKCNT)) < 0) {		prmsg("TASKCNT failed at %s line %d\n",		      DEVNAME_CONTROL, __FILE__, __LINE__);		status = -1;	} else		status = dev_unlink(n_task);	prmsg("releasing resources for DSP\n");	ioctl(cfd, OMAP_DSP_IOCTL_DSPUNCFG);	close(cfd);	if (status < 0)		sendback_event(fd, DLD_EVENT_ERROR);	else		sendback_event(fd, DLD_EVENT_DONE);	return 0;}static int server_suspend(int fd){	int cfd;	int ret;	if ((cfd = open(DEVNAME_CONTROL, O_RDWR)) < 0) {		prmsg("%s open failed at %s line %d\n",		      DEVNAME_CONTROL, __FILE__, __LINE__);		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	prmsg("suspending DSP\n");	ret = ioctl(cfd, OMAP_DSP_IOCTL_SUSPEND);	close(cfd);	if (ret < 0) {		prmsg("SUSPEND failed\n");		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	sendback_event(fd, DLD_EVENT_DONE);	suspend = 1;	return 0;}static int server_resume(int fd){	int cfd;	int ret;	suspend = 0;	if ((cfd = open(DEVNAME_CONTROL, O_RDWR)) < 0) {		prmsg("%s open failed at %s line %d\n",		      DEVNAME_CONTROL, __FILE__, __LINE__);		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	prmsg("resuming DSP\n");	ret = ioctl(cfd, OMAP_DSP_IOCTL_RESUME);	close(cfd);	if (ret < 0) {		prmsg("RESUME failed\n");		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	sendback_event(fd, DLD_EVENT_DONE);	return 0;}static int server_exmap(int fd, struct server_event *e){	struct omap_dsp_mapinfo mapinfo = { e->data.exmap.dspadr,					    e->data.exmap.size };	int ret;	int cfd;	if ((cfd = open(DEVNAME_DSPMEM, O_RDWR)) < 0) {		prmsg("%s open failed at %s line %d\n",		      DEVNAME_CONTROL, __FILE__, __LINE__);		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	prmsg("mapping external memory for DSP: "	      "dspadr = 0x%06lx, size = 0x%lx\n",	      mapinfo.dspadr, mapinfo.size);	ret = ioctl(cfd, OMAP_DSP_MEM_IOCTL_EXMAP, &mapinfo);	close(cfd);	if (ret < 0) {		prmsg("EXMAP failed\n");		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	prmsg("%d bytes mapped.\n", ret);	sendback_event(fd, DLD_EVENT_DONE);	return 0;}static int server_mmuinit(int fd){	int cfd;	if ((cfd = open(DEVNAME_DSPMEM, O_RDWR)) < 0) {		prmsg("%s open failed at %s line %d\n",		      DEVNAME_CONTROL, __FILE__, __LINE__);		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	prmsg("DSP MMU initialize.\n");	ioctl(cfd, OMAP_DSP_MEM_IOCTL_MMUINIT);	close(cfd);	sendback_event(fd, DLD_EVENT_DONE);	return 0;}static int server_mapflush(int fd){	int cfd;	if ((cfd = open(DEVNAME_DSPMEM, O_RDWR)) < 0) {		prmsg("%s open failed at %s line %d\n",		      DEVNAME_CONTROL, __FILE__, __LINE__);		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	prmsg("DSP TLB has been flushed.\n");	ioctl(cfd, OMAP_DSP_MEM_IOCTL_EXMAP_FLUSH);	close(cfd);	sendback_event(fd, DLD_EVENT_DONE);	return 0;}static int server_mbsend(int fd, struct server_event *e){	struct omap_dsp_mailbox_cmd mbcmd = { e->data.mbsend.cmd,					      e->data.mbsend.data };	int cfd;	if ((cfd = open(DEVNAME_CONTROL, O_RDWR)) < 0) {		prmsg("%s open failed at %s line %d\n",		      DEVNAME_CONTROL, __FILE__, __LINE__);		sendback_event(fd, DLD_EVENT_ERROR);		return 1;	}	prmsg("sending mailbox command to DSP: cmd = 0x%02x, data = 0x%02x\n",	      mbcmd.cmd, mbcmd.data);	ioctl(cfd, OMAP_DSP_IOCTL_MBSEND, &mbcmd);	close(cfd);	sendback_event(fd, DLD_EVENT_DONE);	return 0;}#endif /* DSP_EMULATION */#ifndef DSP_EMULATION/* * */int twch_tadd(struct taskent *te){	u32 taskadr;	pid_t pid;#ifdef USE_FORK	if (te->cobj->request_lock++) {		prmsg("device %s is locked. delaying TADD request.\n",		      te->devname);		return 0;	}#endif	/*	 * clear request so that the server detect next request.	 */	te->request = TREQ_NONE;	prmsg("starting TADD process for device %s.\n", te->devname);	taskadr = task_load(te);	pid = fork_task_add(te->minor, taskadr);	if (pid < 0)		exit(1);#ifdef USE_FORK	if (pid == 0)	/* child */		exit(0);#endif	/* parent */	if (taskadr == OMAP_DSP_TADD_ABORTADR)		return 1;	return 0;}int twch_tdel(struct taskent *te){	pid_t pid;#ifdef USE_FORK	if (te->cobj->request_lock++) {		prmsg("device %s is locked. delaying TDEL request.\n",		      te->devname);		return 0;	}#endif	/*	 * clear request so that the server detect next request.	 */	te->request = TREQ_NONE;	prmsg("starting TDEL process for device %s.\n", te->devname);	pid = fork_task_del(te->minor);	if (pid < 0)		exit(1);#ifdef USE_FORK	if (pid == 0) {	/* child */		/*		 * task_clear() will be done when		 * the server received TDEL_DONE event.		 */		exit(0);	}	/* parent */	return 0;#else	return task_clear(te);#endif}static int read_twch(void){	long tstat[TID_MAX];	struct taskent *te;	size_t cnt;	int devcnt;	int i;	if ((cnt = read(server_fds.fd_twch, tstat, TID_MAX * sizeof(long))) < 0) {		prmsg("read from dsptwch failed\n");		return -1;	}	devcnt = cnt / 4;	prmsg("dsp_dld: event detected.\n");	for (i = 0; i < devcnt; i++) {		if ((te = taskent_find_by_minor(i)) == NULL)			continue;		switch (tstat[i]) {			/* if STALE bit is set, it means the request has			 * accepted already, and we ignore it. */			case OMAP_DSP_DEVSTATE_ADDREQ:				prmsg("device %s is requesting for TADD.\n",				      te->devname);				te->request = TREQ_ADD;				break;			case OMAP_DSP_DEVSTATE_DELREQ:				prmsg("device %s is requesting for TDEL.\n",				      te->devname);				te->request = TREQ_DEL;				break;		}	}	memcpy(tstat_prev, tstat, devcnt * sizeof(long));	return taskent_process_request_all();}static server_return_t read_errdt(int fd){	unsigned long errcode;	size_t cnt;	if ((cnt = read(fd, &errcode, 4)) < 0) {		prmsg("read from dsperr failed\n");		return SERVER_RESTART;	}	prmsg("dsp_dld: DSP error detected.\n");	if (errcode & OMAP_DSP_ERRDT_WDT) {		prmsg("  DSP watchdog timer expired.\n"		      "  (some tasks may be in busy loop)\n");		return SERVER_RESTART;	}	if (errcode & OMAP_DSP_ERRDT_MMU) {#if 0 // recovery		int fd_dspmem;		prmsg("  DSP MMU fault. trying to recover...\n");		if ((fd_dspmem = open(DEVNAME_DSPMEM, O_RDWR)) < 0) {			prmsg("%s open failed\n", DEVNAME_DSPMEM);			return SERVER_RESTART;		}		ioctl(fd_dspmem, OMAP_DSP_MEM_IOCTL_MMUITACK);		close(fd_dspmem);#else		prmsg("  DSP MMU fault.\n");		return SERVER_RESTART;#endif	}	return SERVER_OK;}#endif /* !DSP_EMULATION */static int server_open(char *name){	int fd;	struct sockaddr_un addr;	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {		prmsg("socket() failed at %s line %d\n", __FILE__, __LINE__);		return -1;	}	if (!access(name, F_OK))		unlink(name);	addr.sun_family = AF_UNIX;	strcpy(addr.sun_path, name);	if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {		prmsg("bind() failed at %s line %d\n", __FILE__, __LINE__);		return -1;	}	if (listen(fd, 1) < 0) {		prmsg("listen() failed at %s line %d\n", __FILE__, __LINE__);		return -1;	}	return fd;}static int server_close(int fd, char *name){	close(fd);	unlink(name);	return 0;}static int server_accept(int fd){	int fd_acc;	struct sockaddr_un addr;	int len = sizeof(struct sockaddr_un);	if ((fd_acc = accept(fd, (struct sockaddr *)&addr, &len)) < 0) {		prmsg("accept() failed at %s line %d\n", __FILE__, __LINE__);		return -1;	}	return fd_acc;}static server_return_t server_read(void){	char buf[256];	struct server_event *e = (struct server_event *)buf;	int fd = server_fds.fd_acc;	int status = 0;	if (read_event(fd, e, 256) < 0) {		prmsg("failed to read event packet from socket\n");		return SERVER_RESTART;	}	switch (e->event) {		case DLD_EVENT_TADD:			status = server_tadd(e);			break;		case DLD_EVENT_TDEL:			status =  server_tdel(e);			break;		case DLD_EVENT_TKILL:			status = server_tkill(e);			break;		case DLD_EVENT_GETSTAT_TASKENT:			taskent_sendstat(fd);			sendback_event(fd, DLD_EVENT_DONE);			break;		case DLD_EVENT_GETSTAT_MEMMGR:			status = server_sendstat_memmgr(fd);			break;		case DLD_EVENT_GETSTAT_SYMBOL:			status = server_sendstat_symbol(fd);			break;		case DLD_EVENT_GETSTAT_SECTION:			status = server_sendstat_section(fd);			break;		case DLD_EVENT_MEMDUMP:			status = server_memdump(fd, e);			break;		   #ifndef DSP_EMULATION		case DLD_EVENT_DSP_RUN:			status = server_dsp_run(fd);			break;		case DLD_EVENT_DSP_RESET:			status = server_dsp_reset(fd);			break;		case DLD_EVENT_RSTVECT:			status = server_setrstvect(fd, e);			break;		case DLD_EVENT_CPU_IDLE:			status = server_cpu_idle(fd);			break;		   		case DLD_EVENT_DSPCFG:			status = server_dspconfig(fd);			break;		   		case DLD_EVENT_DSPUNCFG:			status = server_dspunconfig(fd);			break;		   		case DLD_EVENT_SUSPEND:			status = server_suspend(fd);			break;		   		case DLD_EVENT_RESUME:			status = server_resume(fd);			break;		   		case DLD_EVENT_EXMAP:			status = server_exmap(fd, e);			break;		case DLD_EVENT_MMUINIT:			status = server_mmuinit(fd);			break;		case DLD_EVENT_MAPFLUSH:			status = server_mapflush(fd);			break;		case DLD_EVENT_MBSEND:			status = server_mbsend(fd, e);			break;#endif /* DSP_EMULATION */		case DLD_EVENT_TERMINATE:			prmsg("Terminating...\n");			sendback_event(fd, DLD_EVENT_DONE);			return SERVER_DONE;		case DLD_EVENT_RESTART:			prmsg("Restarting...\n");			sendback_event(fd, DLD_EVENT_DONE);			return SERVER_RESTART;		default:			sendback_event(fd, DLD_EVENT_ERROR);			prmsg("unknown event packet (%d) received on socket\n",			      e->event);			return SERVER_RESTART;	}	if (status < 0)		return SERVER_RESTART;		return SERVER_OK;}static server_return_t read_all_fds(fd_set testfds){#ifdef USE_FORK	int i;#endif	if (FD_ISSET(server_fds.fd_sock, &testfds)) {		if ((server_fds.fd_acc = server_accept(server_fds.fd_sock)) < 0)			return SERVER_RESTART;		FD_SET(server_fds.fd_acc, &server_fds.set);	}	if ((server_fds.fd_acc >= 0) && FD_ISSET(server_fds.fd_acc, &testfds)) {		server_return_t ret;		ret = server_read();		close(server_fds.fd_acc);		FD_CLR(server_fds.fd_acc, &server_fds.set);		server_fds.fd_acc = -1;		return ret;	}#ifdef USE_FORK	for (i = 0; i < MAX_CHILDREN; i++) {		int fd = server_fds.fd_pipe[i];		if ((fd >= 0) && FD_ISSET(fd, &testfds)) {			int ret;			ret = read_pipe(fd);			close(fd);			FD_CLR(fd, &server_fds.set);			server_fds.fd_pipe[i] = -1;			if (ret < 0)				return SERVER_RESTART;		}	}#endif#ifndef DSP_EMULATION	if (FD_ISSET(server_fds.fd_twch, &testfds)) {		if (read_twch() < 0)			return SERVER_RESTART;		FD_SET(server_fds.fd_twch, &server_fds.set);	}	if (FD_ISSET(server_fds.fd_err, &testfds)) {		server_return_t ret;		if ((ret = read_errdt(server_fds.fd_err)) != SERVER_OK)			return ret;		FD_SET(server_fds.fd_err, &server_fds.set);	}#endif	return SERVER_OK;}server_return_t server(void){	server_return_t ret;	struct timeval timeout;#ifdef USE_FORK	int i;#endif#ifndef DSP_EMULATION	if ((server_fds.fd_twch = open(DEVNAME_TWCH, O_RDONLY)) < 0) {		prmsg("%s open failed\n", DEVNAME_TWCH);		return SERVER_ERROR;	}	if ((server_fds.fd_err = open(DEVNAME_ERR, O_RDONLY)) < 0) {		prmsg("%s open failed\n", DEVNAME_ERR);		return SERVER_ERROR;	}#endif	if (taskent_mkdev(server_fds.fd_twch) < 0)		return SERVER_ERROR;	if ((server_fds.fd_sock = server_open(SOCK_NAME)) < 0)		return SERVER_ERROR;	FD_ZERO(&server_fds.set);#ifndef DSP_EMULATION	FD_SET(server_fds.fd_twch, &server_fds.set);	FD_SET(server_fds.fd_err, &server_fds.set);#endif	FD_SET(server_fds.fd_sock, &server_fds.set);	server_fds.fd_acc = -1;#ifdef USE_FORK	for (i = 0; i < MAX_CHILDREN; i++) {		server_fds.fd_pipe[i] = -1;	}#endif /* USE_FORK */	timeout.tv_sec  = 10;	timeout.tv_usec = 0;	for (;;) {		fd_set testfds = server_fds.set;		int sel_result;		sel_result = select(FD_SETSIZE, &testfds, NULL, NULL, &timeout);		if (signal_received) {			if (signal_action == SERVER_OK) {				signal_received = 0;				continue;			} else				break;		}		if (sel_result < 0) {			prmsg("select() failed at %s line %d\n",			      __FILE__, __LINE__);			ret = SERVER_ERROR;			break;		} else if (sel_result == 0) {	/* timeout */#if !(defined DSP_EMULATION) && (defined ENABLE_POLL)			int cfd;			int status;			if (suspend)				goto poll_out;			if (binary_version < 0x00030003)				goto poll_out;			/*			 * we assume this program runs on Linux,			 * so the timeout value is decreased within			 * select(), therefore timeout occurs even if			 * other events wakes select() up frequently.			 */			if ((cfd = open(DEVNAME_CONTROL, O_RDWR)) < 0) {				prmsg("%s open failed at %s line %d\n",				      DEVNAME_CONTROL, __FILE__, __LINE__);				ret = SERVER_RESTART;				break;			}			/* FIXME: fork this polling process */			status = ioctl(cfd, OMAP_DSP_IOCTL_POLL);			close(cfd);			if (status < 0) {				ret = SERVER_RESTART;				break;			}poll_out:#endif /* !(defined DSP_EMULATION) && (defined ENABLE_POLL) */			timeout.tv_sec  = 10;			timeout.tv_usec = 0;		} else {			if ((ret = read_all_fds(testfds)) != SERVER_OK)				break;		}	}	taskent_rmdev(server_fds.fd_twch);	if (server_fds.fd_acc > 0)		close(server_fds.fd_acc);	server_close(server_fds.fd_sock, SOCK_NAME);#ifndef DSP_EMULATION	close(server_fds.fd_twch);	close(server_fds.fd_err);#endif	/* signal overrides poll timeout or other error */	if (signal_received)		ret = signal_action;	return ret;}#undef SIGHUP_RESTARTvoid dspsig_handler(int signum){	prmsg("receiving signal %d\n", signum);	signal_received = signum;	if (signum == SIGCHLD) {		pid_t pid;		signal_action = SERVER_OK;		do {			pid = waitpid(-1, NULL, WNOHANG);		} while (pid > 0);		return;	}	if (signum == SIGKILL)		exit(0);	signal_action = SERVER_DONE;#ifdef SIGHUP_RESTART	if (signum == SIGHUP)		signal_action = SERVER_RESTART;#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -