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

📄 supertask.c

📁 TI OMAP 1510上mcbsp的驱动程序
💻 C
字号:
/* * dspapps/dsp/tokliBIOS/supertask.c * * OMAP DSP bridge DSP-side core library * supertask module * * Copyright (C) 2002,2003 Nokia Corporation * * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: supertask.c * $Revision: 2.0 * $Date: 2003/11/11 * */#include <std.h>#include <sem.h>#include <tsk.h>#include "omap1510.h"#include "mailbox.h"#include "tokliBIOS.h"#include "tokliBIOSlib.h"#include "toklibioscfg.h"struct mailboxq_super {	Uns	cmd_h;	Uns	cmd_l;	Uns	data;};#define MBQ_MAX	8struct supertask {	Uns		mbq_wp, mbq_rp;	struct mailboxq_super	mbq[MBQ_MAX];};static struct supertask	super;static Void do_super(Uns cmd_h, Uns cmd_l, Uns data);#ifndef BKYLD_IN_INTHANDLERstatic Uns super_bkyld(Uns bid);#endif /* BKYLD_IN_INTHANDLER */static Uns super_dspcfg(Uns cfgtyp);static Uns super_regrw(Uns cmd_l, Uns ad);static Uns super_getvar(Uns varid);static Uns super_setvar(Uns varid, Uns val);static Uns super_tadd(Uns bid);static Uns super_tdel(Uns tid);Void init_super(Void){	super.mbq_wp = super.mbq_rp = 0;}/* * supervisor task function */Void supertask(Void){	struct mailboxq_super	*mbq = super.mbq;	Uns	*rp = &super.mbq_rp;	Uns	intm_saved;	Int	mbq_full;start:	SEM_pend(&SEM_super, SYS_FOREVER); // wait for next one	do_super(mbq[*rp].cmd_h, mbq[*rp].cmd_l, mbq[*rp].data);	intm_saved = HWI_disable();	mbq_full = (*rp == super.mbq_wp);	if(++*rp == MBQ_MAX)		*rp = 0;	/*	 * interrupt had been disabled in case the mbq has been full.	 * now we have a space to accept.	 */	if(mbq_full)		*_IER0 |= _IER0_BIT_MAILBOX1;	HWI_restore(intm_saved);	goto start;}static Void do_super(Uns cmd_h, Uns cmd_l, Uns data){	Uns	eid;	switch(cmd_h) {#ifndef BKYLD_IN_INTHANDLER		case MBCMD_BKYLD:			eid = super_bkyld(data);			return;#endif /* BKYLD_IN_INTHANDLER */		case MBCMD_DSPCFG:			eid = super_dspcfg(cmd_l);			return;		case MBCMD_REGRW:			eid = super_regrw(cmd_l, data);			return;		case MBCMD_GETVAR:			eid = super_getvar(cmd_l);			return;		case MBCMD_SETVAR:			eid = super_setvar(cmd_l, data);			return;		case MBCMD_TADD:			eid = super_tadd(data);			break;		case MBCMD_TDEL:			eid = super_tdel(cmd_l);			break;		default:			eid = MBCMD_EID_BADCMD;	}	if(eid) {		sys_cmderr(eid, mbcmd(cmd_h, cmd_l));	}}#ifndef BKYLD_IN_INTHANDLERstatic Uns super_bkyld(Uns bid){	Uns	eid;	if(eid = sync_ipbuf_anon(bid))		return eid;	if(eid = release_ipbuf(bid))		return eid;	return 0;}#endif /* BKYLD_IN_INTHANDLER */static Uns super_regrw(Uns cmd_l, Uns ad){	static Uns	last_cmd_l = MBCMD_REGRW_MEMR;	static Uns	last_ad = 0;	Uns	ret = 0;	switch(cmd_l) {		case MBCMD_REGRW_MEMR:			mbsend(mbcmd(MBCMD_REGRW, MBCMD_REGRW_DATA),			       *(Uns*)ad);			break;		case MBCMD_REGRW_IOR:			mbsend(mbcmd(MBCMD_REGRW, MBCMD_REGRW_DATA),			       inw(ad));			break;		case MBCMD_REGRW_MEMW:		case MBCMD_REGRW_IOW:			break;		case MBCMD_REGRW_DATA:			switch(last_cmd_l) {				case MBCMD_REGRW_MEMW:					*(Uns*)last_ad = ad;					break;				case MBCMD_REGRW_IOW:					outw(ad, last_ad);					break;				default:					ret = MBCMD_EID_BADCMD;			}			break;		default:			ret = MBCMD_EID_BADCMD;	}	last_cmd_l = cmd_l;	last_ad = ad;	return ret;}static Uns super_setvar(Uns varid, Uns val){	switch(varid) {		case MBCMD_VARID_ICRMASK:			set_icr_mask(val);			return 0;		default:			return MBCMD_EID_BADCMD;	}}static Uns super_getvar(Uns varid){	switch(varid) {		case MBCMD_VARID_ICRMASK:			mbsend(mbcmd(MBCMD_GETVAR, MBCMD_VARID_ICRMASK),			       get_icr_mask());			return 0;		default:			return MBCMD_EID_BADCMD;	}}static Uns super_dspcfg(Uns cfgtyp){	static struct cfgbuf {		Uns	task_max;		Uns	bln;		Uns	bsz;		Uns	badrh;		Uns	badrl;		Uns	bkeep;	} cfgbuf;	init_timer(); // overwriting DSP/BIOS's settings	if(cfgtyp != MBCMD_DSPCFG_REQ) {		return MBCMD_EID_BADCFGTYP;	}	cfgbuf.task_max = _n_task;	cfgbuf.bln      = _ipbuf_lines;	cfgbuf.bsz      = _ipbuf_sz;	cfgbuf.badrh    = (LgUns)&_ipbuf_body >> 16;	cfgbuf.badrl    = (LgUns)&_ipbuf_body & 0xffff;	cfgbuf.bkeep    = _ipbuf_keep;	ipbuf_sys.c  = sizeof(struct cfgbuf);	ipbuf_sys.s  = MBCMD_TID_ANON;	ipbuf_sys.ah = (LgUns)&cfgbuf >> 16;	ipbuf_sys.al = (LgUns)&cfgbuf & 0xffff;	mbsend(mbcmd(MBCMD_DSPCFG, MBCMD_DSPCFG_PROTREV),	       MBPROT_REVISION);	mbsend(mbcmd(MBCMD_DSPCFG, MBCMD_DSPCFG_SYSADRH),	       (LgUns)&ipbuf_sys >> 16);	mbsend(mbcmd(MBCMD_DSPCFG, MBCMD_DSPCFG_SYSADRL | MBCMD_DSPCFG_LAST),	       (LgUns)&ipbuf_sys & 0xffff);	init_ipbuf();	return 0;}static Uns super_tadd(Uns bid){	struct dsptask	*new;	struct task_prop	*prop;	Uns	*ipbd;	Uns	tid;	if(ipbuf[bid]->c != 2) {		return MBCMD_EID_BADCNT;	}	ipbd = ipbuf_d[bid];	new = (Void*)(((LgUns)ipbd[0] << 16) | ipbd[1]);	unuse_ipbuf(&task_anon, bid);#ifdef DEBUG_TADD	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), new->tid);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), ((LgUns)new->name)>>16);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), ((LgUns)new->name)&0xffff);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), new->ttyp);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), ((LgUns)new->rcv_snd)>>16);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), ((LgUns)new->rcv_snd)&0xffff);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), ((LgUns)new->rcv_req)>>16);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), ((LgUns)new->rcv_req)&0xffff);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), ((LgUns)new->rcv_tctl)>>16);	mbsend(mbcmd(MBCMD_ERR, MBCMD_EID_DEBUG), ((LgUns)new->rcv_tctl)&0xffff);#endif	/*	 * new task validation	 */	if(new->tid != TID_MAGIC) {		return MBCMD_EID_BADADR;	}	/*	 * OK, welcome.	 */	for(tid=_n_task; tid<N_TASK_MAX; tid++) {		if(dsptask[tid] == NULL)			goto found;	}	// no room in task pointer	return MBCMD_EID_NORES;found:	prop = MEM_alloc(MEM->MALLOCSEG, sizeof(struct task_prop), 2);	if(prop == MEM_ILLEGAL) {		return MBCMD_EID_NOMEM;	}	task_config(new, prop, tid);	mbsend(mbcmd(MBCMD_TADD, tid), 0);	return 0;}static Uns super_tdel(Uns tid){	if((tid < _n_task) ||	   (tid >= N_TASK_MAX) ||	   (dsptask[tid] == NULL)) {		return MBCMD_EID_BADTID;	}	// note: task_unconfig() sets task_prop[tid]=NULL.	task_unconfig(tid);	MEM_free(MEM->MALLOCSEG, task_prop[tid], sizeof(struct task_prop));	mbsend(mbcmd(MBCMD_TDEL, tid), 0);	return 0;}/* * registering command to supertask's mbq. */Void register_super_mbq(Uns cmd_h, Uns cmd_l, Uns data){	struct mailboxq_super	*mbq_ent;	Uns	*wp;	wp = &super.mbq_wp;	mbq_ent = &super.mbq[*wp];	mbq_ent->cmd_h = cmd_h;	mbq_ent->cmd_l = cmd_l;	mbq_ent->data  = data;	if(++*wp == MBQ_MAX)		*wp = 0;	if(*wp == super.mbq_rp) // mbq is full!		*_IER0 &= ~_IER0_BIT_MAILBOX1; // disable interrupt	SEM_post(&SEM_super);}

⌨️ 快捷键说明

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