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

📄 dld_memmgr.c

📁 Omap5910 上实现双核通信 DSP GateWay
💻 C
📖 第 1 页 / 共 2 页
字号:
	return NULL;}struct memmgr *memmgr_find_by_addr(struct list_head *list, u32 base, u32 size){	struct memmgr *mem;	/*	 * search in local list	 */	if (list && (list != &g_memlist)) {		memmgr_for_each(mem, list) {			if ((base >= mem->base) &&			    (base + size <= mem->base + mem->size))				return mem;	/* found! */		}	}	/*	 * search in global list	 */	memmgr_for_each(mem, &g_memlist) {		if ((base >= mem->base) &&		    (base + size <= mem->base + mem->size))			return mem;	/* found! */	}	/* not found */	return NULL;}struct memmgr *memmgr_find_by_name(struct list_head *list, char *name){	struct memmgr *mem;	/*	 * search in local list	 */	if (list && (list != &g_memlist)) {		memmgr_for_each(mem, list) {			if (!strcmp(mem->name, name))				return mem;	/* found! */		}	}	/*	 * search in global list	 */	memmgr_for_each(mem, &g_memlist) {		if (!strcmp(mem->name, name))			return mem;	/* found! */	}	/* not found */	return NULL;}/* * memory space */#define spaceof(a) \	(((a) < DSP_MEM_SIZE) ? SPACE_INTERNAL : \	 ((a) < VECTPG_BASE) ? SPACE_EXTERN : \	 SPACE_VECTPG)int space_find_by_addr(u32 addr, u32 size){	int space = spaceof(addr);	if (spaceof(addr + size - 1) == space)		return space;	else		return SPACE_CROSSING;}void memmgr_occupy_kernel(struct list_head *scnlist){	/*	 * use only g_memlist	 */	struct section *scn;	struct memmgr *mem;	/*	 * search the highest address of the area allocated	 * for kernel sections	 */	section_for_each(scn, scnlist) {		u32 scnend;		if (scn->size == 0)			continue;		mem = memmgr_find_by_addr(NULL, scn->vaddr, scn->size);		if (mem == NULL)			continue;		scnend = scn->vaddr + scn->size;		if (scnend > mem->seg_base)			mem->seg_base = scnend;	}	memmgr_for_each(mem, &g_memlist) {		struct memseg *seg;#if 0		u32 a;		/*		 * decide segment align according to the memory size		 */		mem->seg_align = 1;		a = mem->base + mem->size - mem->seg_base;		while (a >>= 1) {			mem->seg_align <<= 1;		}		mem->seg_align >>= 4;	/* max 32 segments */		if (mem->seg_align == 0)			mem->seg_align = 1;		mem->seg_base = ceil_int(mem->seg_base, mem->seg_align);#endif		seg = list_entry(mem->seglist.next, struct memseg, list_head);		seg->base = mem->seg_base;		seg->wp   = mem->seg_base;		seg->end  = mem->base + mem->size;	}}int memmgr_placetask(struct taskent *te, struct coffobj *cobj,		     struct lkcmd *gbl_lkcmd){	struct section *scn;	struct symbol *sym;	section_for_each(scn, &cobj->scnlist) {#if 0	/* allow non-zero section address */		if (scn->vaddr != 0) {			prmsg("section %s: "			      "attempted to place the section "			      "which has address value (0x%08lx)???\n",			      scn->name, scn->vaddr);			break;		}#endif		/*		 * RAM model initialization		 * Do not allocate real memory to .cinit.		 */		if (!strcmp(scn->name, ".cinit")) {			scn->flags |= COFF_STYP_COPY;			continue;		}		/* search in task specific directive */		if (te->lkcmd &&		    (placescn(te, scn, te->lkcmd,			      PLACE_MODE_EXACTNAME) != NULL))			goto place_done;		/* search in global directive */		if (placescn(te, scn, gbl_lkcmd,			     PLACE_MODE_EXACTNAME) != NULL)			goto place_done;		/*		 * if section name contains ':' (ex. .text:aaa),		 * try with its basename.		 */		if (strchr(scn->name, ':')) {			/* search in task specific directive */			if (te->lkcmd &&			    (placescn(te, scn, te->lkcmd,				      PLACE_MODE_BASENAME) != NULL))				goto place_done;			/* search in global directive */			if (placescn(te, scn, gbl_lkcmd,				     PLACE_MODE_BASENAME) != NULL)				goto place_done;		}		/* place anywhere */		prmsg("section %s: could not find directive. ", scn->name);		if (placescn(te, scn, NULL, PLACE_MODE_ANYWHERE) != NULL)			goto place_done;		prmsg("section %s: failed to place!\n", scn->name);		return -1;place_done:		/* update all symbol values in this section */		symbol_for_each(sym, &cobj->symlist) {			if (sym->scn == scn) {				sym->value += scn->vaddr - scn->vaddr_orig;			}		}	}	return 0;}static struct memmgr *placescn(struct taskent *te, struct section *scn,			       struct lkcmd *lkcmd, unsigned int mode){	struct directive *dir;	struct memmgr *mem;	struct list_head *dirlist;	struct list_head *memlist;	u32 align;	if (place_mode_anywhere(mode)) {		dir = &directive_default;		mem = memmgr_default();		prmsg("placing it to default memory (%s).\n", mem->name);		goto do_place;	}	/* can be null only when STICKY_LIST */	dirlist = lkcmd ? &lkcmd->dirlist : NULL;	if (place_mode_basename(mode)) {		/*		 * if this function called with basename mode,		 * the section name must contain ':'.		 */		char *tmpname;		tmpname = strdup(scn->name);		*strchr(tmpname, ':') = '\0';		dir = directive_find_by_scnnm(dirlist, tmpname);		free(tmpname);	} else		dir = directive_find_by_scnnm(dirlist, scn->name);	if (dir == NULL)		return NULL;	/*	 * FIXME: dir can have constant addr!	 */	if (dir->load.mem == NULL) {		prmsg("section %s: "		      "could not get memory property for "		      "directive...\n", scn->name);		return NULL;	}	/* can be null only when STICKY_LIST */	memlist = lkcmd ? &lkcmd->memlist : NULL;	mem = memmgr_find_by_name(memlist, dir->load.mem);do_place:	if ((align = dir->load.align) == 0) {		/* use default align */		if (scn->flags & COFF_STYP_BSS)			align = 4;	/* bss section (XXX: Is this true?) */		else if (scn->flags & COFF_STYP_TEXT)			align = 1;	/* text section */		else#if 0			align = 2;	/* data section */#else			align = 4;	/* data section // XXX: for secure ... Is it needed? */#endif	}	scn->vaddr = memmgr_malloc(mem, te, scn->size, align);	if (scn->vaddr == DSPADDR_ILLEGAL) {		prmsg("section %s: size = 0x%06x, align = 0x%x ... "		      "no space left in %s!\n",		      scn->name, scn->size, align, mem->name);		return NULL;	}	return mem;}void memmgr_cleartask(struct taskent *te){	struct memmgr *mem;	struct memseg *seg, *tmp;	memmgr_for_each(mem, &g_memlist) {		memseg_for_each_safe(seg, tmp, &mem->seglist) {			if (seg->cobj == te->cobj)				memmgr_freeseg(seg);		}	}}void memmgr_sendstat(struct list_head *list, int fd){	struct memmgr *mem;	struct memseg *seg;	char buf[256];	size_t strsz = 256 - SERVER_EVENT_HDRSZ;	struct server_event *e = (struct server_event *)buf;	int cnt;	if (list == NULL)		list = &g_memlist;	e->event = DLD_EVENT_STRING;	cnt = snprintf(e->data.s, strsz,		       "%-10s %-6s %-6s %-6s  %-6s %-6s %-6s %-20s\n",		       "name", "base", "size", "sgbase",		       "sgbase", "segwp", "segend", "task");	e->len = SERVER_EVENT_HDRSZ + cnt;	write(fd, e, e->len);	memmgr_for_each(mem, list) {		cnt = snprintf(e->data.s, strsz,			       "%-10s %06lx %06lx %06lx\n",			       mem->name, mem->base, mem->size, mem->seg_base);		e->len = SERVER_EVENT_HDRSZ + cnt;		write(fd, e, e->len);		memseg_for_each(seg, &mem->seglist) {			cnt = snprintf(e->data.s, strsz,				       "%10s %6s %6s %6s  %06lx %06lx %06lx %-20s\n",				       "", "", "", "",				       seg->base, seg->wp, seg->end,				       seg->cobj ? seg->cobj->fn : "(none)");			e->len = SERVER_EVENT_HDRSZ + cnt;			write(fd, e, e->len);		}	}}/* * debug stuff */void memmgr_printstat(struct list_head *list){	struct memmgr *mem;	struct memseg *seg;	if (list == NULL)		list = &g_memlist;	prmsg("memmgr list status...\n");	prmsg("  %-10s %-6s %-6s %-6s  %-6s %-6s %-6s %-20s\n",	      "name", "base", "size", "sgbase",	      "sgbase", "segwp", "segend", "task");	memmgr_for_each(mem, list) {		prmsg("  %-10s %06lx %06lx %06lx\n",		      mem->name, mem->base, mem->size, mem->seg_base);		memseg_for_each(seg, &mem->seglist) {			prmsg("  %10s %6s %6s %6s  %06lx %06lx %06lx %-20s\n",			      "", "", "", "",			      seg->base, seg->wp, seg->end,			      seg->cobj ? seg->cobj->fn : "(none)");		}	}}/* * memseg */static struct memseg *memseg_new(u32 base, u32 size){	struct memseg *seg = dld_malloc(sizeof(struct memseg), "memseg");	if (seg == NULL)		return NULL;	seg->base = base;	seg->end  = base + size;	seg->wp   = base;	seg->cobj = NULL;	return seg;}static void memseg_freelist(struct list_head *list){	struct memseg *seg, *tmp;	memseg_for_each_safe(seg, tmp, list) {		list_del(&seg->list_head);		dld_free(seg, "memseg");	}}

⌨️ 快捷键说明

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