📄 supertask.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 + -