📄 dsp_dld.c
字号:
return 0;}int dev_unlink(int n){ int fd; int i; int ret = 0; char name[OMAP_DSP_TNM_LEN]; char path1[20]; char path2[20 + OMAP_DSP_TNM_LEN]; for (i = 0; i < n; i++) { sprintf(path1, "/dev/dsptask%d", i); if ((fd = open(path1, O_RDWR)) < 0) { /* dynamic device file system (devfs, udev) */ continue; } if (ioctl(fd, OMAP_DSP_TASK_IOCTL_GETNAME, name) < 0) { prmsg("GETNAME for %s failed\n", path1); ret = -1; continue; } close(fd); sprintf(path2, TASKDEV_DIR "/%s", name); if (unlink(path2) < 0) { prmsg("unlink(%s) failed\n", path2); ret = -1; continue; } } return ret;}#endif /* DSP_EMULATION */static int dsp_cleanup(void){#ifndef DSP_EMULATION int n_task; int fd_ctl, fd_mem; fd_ctl = open(DEVNAME_CONTROL, O_RDWR); if (fd_ctl < 0) { prmsg("%s open failed at %s line %d\n", DEVNAME_CONTROL, __FILE__, __LINE__); return -1; } fd_mem = open(DEVNAME_DSPMEM, O_RDWR); if (fd_mem < 0) { prmsg("%s open failed at %s line %d\n", DEVNAME_DSPMEM, __FILE__, __LINE__); close(fd_ctl); return -1; } if ((n_task = ioctl(fd_ctl, OMAP_DSP_IOCTL_TASKCNT)) < 0) prmsg("TASKCNT failed at %s line %d\n", __FILE__, __LINE__); else dev_unlink(n_task); ioctl(fd_ctl, OMAP_DSP_IOCTL_DSPUNCFG); ioctl(fd_ctl, OMAP_DSP_IOCTL_RESET); ioctl(fd_mem, OMAP_DSP_MEM_IOCTL_EXMAP_FLUSH); ioctl(fd_mem, OMAP_DSP_MEM_IOCTL_MMUINIT); close(fd_mem); close(fd_ctl);#endif /* DSP_EMULATION */ return 0;}struct COFF_dspgw_version { char major[2]; char minor[2]; char extra1[2]; char extra2[2];};#define COFF_DSPGW_VERSION struct COFF_dspgw_version#define COFF_DSPGW_VERSION_SZ 8#define LEu16(p) ((u16)(((u16)(p)[0])<<8) | \ ((u16)(p)[1]))static void read_binary_version(struct coffobj *cobj){ struct section *scn; COFF_DSPGW_VERSION *v; u16 major, minor, extra1, extra2; binary_version = 0; if ((scn = section_find_by_name(&cobj->scnlist, "dspgw_version")) == NULL) { prmsg("failed to read binary version.\n"); return; } if (!scn->data || (scn->size < COFF_DSPGW_VERSION_SZ)) return; v = (COFF_DSPGW_VERSION *)scn->data; major = LEu16(v->major); minor = LEu16(v->minor); extra1 = LEu16(v->extra1); extra2 = LEu16(v->extra2); binary_version = (major << 16) | minor; prmsg("detected binary version %d.%d.%d.%d\n", major, minor, extra1, extra2);}static int start_kernel(struct coffobj *cobj){#ifndef DSP_EMULATION int n_task; int fd; struct stat dir_stat; if (stat(TASKDEV_DIR, &dir_stat) < 0) { if (mkdir(TASKDEV_DIR, 0755) < 0) { prmsg("mkdev(%s) failed at %s line %d\n", TASKDEV_DIR, __FILE__, __LINE__); return -1; } } else { if (!S_ISDIR(dir_stat.st_mode)) { prmsg(TASKDEV_DIR " is not a directory.\n"); return -1; } } fd = open(DEVNAME_CONTROL, O_RDWR); if (fd < 0) { prmsg("%s open failed at %s line %d\n", DEVNAME_CONTROL, __FILE__, __LINE__); return -1; } /* load */ ioctl(fd, OMAP_DSP_IOCTL_MPUI_BYTESWAP_OFF);#endif /* DSP_EMULATION */ if (section_load(&cobj->scnlist, NULL) < 0) return -1;#ifndef DSP_EMULATION usleep(10000); /* wait for DSP memory settled */ ioctl(fd, OMAP_DSP_IOCTL_RESET); prmsg("setting DSP reset vector to 0x%06lx\n", cobj->entry); ioctl(fd, OMAP_DSP_IOCTL_SETRSTVECT, cobj->entry); prmsg("releasing DSP reset\n"); ioctl(fd, OMAP_DSP_IOCTL_RUN); usleep(10000); /* wait for DSP initialization */ prmsg("DSP configuration ...\n"); if (ioctl(fd, OMAP_DSP_IOCTL_DSPCFG) < 0) { prmsg(" failed\n"); close(fd); return -1; } prmsg(" succeeded.\n"); if ((n_task = ioctl(fd, OMAP_DSP_IOCTL_TASKCNT)) < 0) { prmsg("TASKCNT failed at %s line %d\n", __FILE__, __LINE__); close(fd); return -1; } close(fd); if (dev_mklink(n_task) < 0) return -1;#endif /* DSP_EMULATION */ return 0;}static int stop_kernel(void){#ifndef DSP_EMULATION int n_task; int fd; fd = open(DEVNAME_CONTROL, O_RDWR); if (fd < 0) { prmsg("%s open failed at %s line %d\n", DEVNAME_CONTROL, __FILE__, __LINE__); return -1; } if ((n_task = ioctl(fd, OMAP_DSP_IOCTL_TASKCNT)) < 0) { prmsg("TASKCNT failed at %s line %d\n", __FILE__, __LINE__); } else dev_unlink(n_task); prmsg("releasing resources for DSP\n"); ioctl(fd, OMAP_DSP_IOCTL_DSPUNCFG); prmsg("DSP reset\n"); ioctl(fd, OMAP_DSP_IOCTL_RESET); close(fd);#endif /* DSP_EMULATION */ return 0;}#define __symbol_printstat_1(list) \ do { \ prmsg("\nsymbols before resolve\n"); \ symbol_printstat(list); \ } while (0)#define __symbol_printstat_2(list) \ do { \ prmsg("\nsymbols after resolve\n"); \ symbol_printstat(list); \ } while (0)#define __symbol_printstat_3(list) \ do { \ prmsg("\nsymbols after placement\n"); \ symbol_printstat(list); \ } while (0)#define __memmgr_printstat_1(list) \ do { \ prmsg("\nlocal memmgr before load\n"); \ memmgr_printstat(list); \ } while (0)#define __memmgr_printstat_2(list) \ do { \ prmsg("\nlocal memmgr after load\n"); \ memmgr_printstat(list); \ } while (0)#define __memmgr_printstat_3(list) \ do { \ prmsg("\nkernel memmgr after load\n"); \ memmgr_printstat(list); \ } while (0)#define __section_printstat_1(list) \ do { \ prmsg("\nsections before placement\n"); \ section_printstat(list); \ } while (0)#define __section_printstat_2(list) \ do { \ prmsg("\nsections after placement\n"); \ section_printstat(list); \ } while (0)#ifdef DEBUG_SYMBOL# define symbol_printstat_1(list) __symbol_printstat_1(list)# define symbol_printstat_2(list) __symbol_printstat_2(list)# define symbol_printstat_3(list) __symbol_printstat_3(list)#endif#ifdef DEBUG_MEMMGR# define memmgr_printstat_1(list) __memmgr_printstat_1(list)# define memmgr_printstat_2(list) __memmgr_printstat_2(list)# define memmgr_printstat_3(list) __memmgr_printstat_3(list)#endif#ifdef DEBUG_SECTION# define section_printstat_1(list) __section_printstat_1(list)# define section_printstat_2(list) __section_printstat_2(list)#endif#ifdef DEBUG_RESOLVE# define symbol_printstat_1(list) __symbol_printstat_1(list)# define symbol_printstat_2(list) __symbol_printstat_2(list)#endif#ifdef DEBUG_PLACEMENT# define symbol_printstat_2(list) __symbol_printstat_2(list)# define symbol_printstat_3(list) __symbol_printstat_3(list)# define section_printstat_1(list) __section_printstat_1(list)# define section_printstat_2(list) __section_printstat_2(list)# define memmgr_printstat_2(list) __memmgr_printstat_2(list)# define memmgr_printstat_3(list) __memmgr_printstat_3(list)#endif#ifndef symbol_printstat_1# define symbol_printstat_1(list) do {} while (0)#endif#ifndef symbol_printstat_2# define symbol_printstat_2(list) do {} while (0)#endif#ifndef symbol_printstat_3# define symbol_printstat_3(list) do {} while (0)#endif#ifndef memmgr_printstat_1# define memmgr_printstat_1(list) do {} while (0)#endif#ifndef memmgr_printstat_2# define memmgr_printstat_2(list) do {} while (0)#endif#ifndef memmgr_printstat_3# define memmgr_printstat_3(list) do {} while (0)#endif#ifndef section_printstat_1# define section_printstat_1(list) do {} while (0)#endif#ifndef section_printstat_2# define section_printstat_2(list) do {} while (0)#endifu32 task_load(struct taskent *te){#ifndef STICKY_LIST struct coffobj *knl_cobj = NULL;#endif struct lkcmd *gbl_lkcmd = NULL; struct list_head *knl_symlist = NULL; struct coffobj *cobj = te->cobj; struct symbol *tasksym; LIST_HEAD(memlist); /* * if this task has been loaded already, share the object. */ if (cobj->usecount++ > 0) goto find_tasksym;#ifndef STICKY_LIST knl_cobj = coff_new(dld_conf.knlfn); if (coff_read_kernel(knl_cobj) < 0) goto abort; knl_symlist = &knl_cobj->symlist; gbl_lkcmd = lkcmd_new(dld_conf.cmdfn); if (lkcmd_read(gbl_lkcmd) < 0) goto abort; memmgr_freelist(&gbl_lkcmd->memlist);#endif prmsg("loading %s.\n", cobj->fn); if (coff_read_task(cobj) < 0) goto abort; symbol_printstat_1(&cobj->symlist); if (te->lkcmd) { struct lkcmd *lcl_lkcmd = lkcmd_new(te->lkcmd->fn); if (lkcmd_read(lcl_lkcmd) < 0) goto abort; if (taskent_register_lkcmd(te, lcl_lkcmd) < 0) goto abort; lkcmd_free(lcl_lkcmd); memmgr_printstat_1(&te->lkcmd->memlist); } if (symbol_resolve(knl_symlist, &cobj->symlist) < 0) { prmsg("link failed.\n"); goto abort; } symbol_printstat_2(&cobj->symlist); section_printstat_1(&cobj->scnlist); if (memmgr_placetask(te, cobj, gbl_lkcmd) < 0) goto abort; symbol_printstat_3(&cobj->symlist); section_printstat_2(&cobj->scnlist); if (section_relocate(&cobj->scnlist) < 0) goto abort; if (section_load(&cobj->scnlist, te) < 0) goto abort; memmgr_printstat_2(NULL); if (te->lkcmd) memmgr_printstat_3(&te->lkcmd->memlist);#ifndef STICKY_LIST coff_free(knl_cobj); lkcmd_free(gbl_lkcmd);#endiffind_tasksym: tasksym = symbol_find_by_name(&cobj->symlist, te->taskname); if (tasksym == NULL) { prmsg("symbol %s not found.\n", te->taskname); return OMAP_DSP_TADD_ABORTADR; }#if 0 /* * We do not free the coff objecct here... * It can be used for debugging. */ coff_clear(cobj);#endif prmsg("adding %s(@%06lx) into system.\n", te->taskname, tasksym->value); return tasksym->value;abort:#ifndef STICKY_LIST if (knl_cobj) coff_free(knl_cobj); if (gbl_lkcmd) lkcmd_free(gbl_lkcmd);#endif task_clear(te); return OMAP_DSP_TADD_ABORTADR;}int task_clear(struct taskent *te){ struct coffobj *cobj = te->cobj; prmsg("cleaning task %s...\n", te->devname); if (--cobj->usecount > 0) { return 0; } if (te->lkcmd) lkcmd_clear(te->lkcmd); coff_clear(cobj); prmsg("unloading %s.\n", cobj->fn); memmgr_cleartask(te); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -