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

📄 bus.c

📁 skyeye_1_2_2_Rel.rar 最新skyeye源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ---------------------------------------------------------- * Add a mapping to the linked list of mappings of device * ----------------------------------------------------------- */void Mem_AreaAddMapping(BusDevice *bdev,uint32_t base,uint32_t mapsize,uint32_t flags) {	MemMapping *mapping=malloc(sizeof(MemMapping));	if(!mapping) {		fprintf(stderr,"Out of memory allocating MemMaping\n");		exit(837);	}	mapping->next=bdev->first_mapping;	bdev->first_mapping=mapping;	mapping->base=base;	mapping->mapsize = mapsize;	mapping->flags = flags & bdev->hw_flags;	bdev->Map(bdev->owner,base,mapping->mapsize,flags);	/* Check for traces ??? */        /* Need to Invalidate Tlb because we cache Host Virtual Addresses */	if(InvalidateProc) {		InvalidateProc();	}}/* * --------------------------------------------------------------------------------- * Map a range *	Forwards all decoded bits (devsize-1) to the device *	This function may only called by device emulators in response to *	a map request.  * --------------------------------------------------------------------------------- */ voidMem_MapRange(uint32_t base,uint8_t *start_mem,uint32_t devsize,uint32_t mapsize,uint32_t flags) {	uint32_t count=0;	uint32_t addr;	uint32_t pos=base & (devsize-1);	uint8_t *mem = start_mem+pos; 	for(addr=base; 1 ;) {		if((mapsize>=MEM_MAP_BLOCKSIZE) && !(addr & MEM_MAP_BLOCKMASK)) {			Mem_MapBlock(addr,mem,flags);			mem+=MEM_MAP_BLOCKSIZE;			pos+=MEM_MAP_BLOCKSIZE;			count+=MEM_MAP_BLOCKSIZE;			addr+=MEM_MAP_BLOCKSIZE;			mapsize-=MEM_MAP_BLOCKSIZE;		} else if((mapsize >= twoLevelMMap.scnd_lvl_blocksize) && !(addr & twoLevelMMap.scnd_lvl_blockmask)) {			Mem_Map2LvlBlock(addr,mem,flags);			mem+=twoLevelMMap.scnd_lvl_blocksize;			pos+=twoLevelMMap.scnd_lvl_blocksize;			count+=twoLevelMMap.scnd_lvl_blocksize;			addr+=twoLevelMMap.scnd_lvl_blocksize;			mapsize-=twoLevelMMap.scnd_lvl_blocksize;		} else {			if(mapsize) {				fprintf(stderr,"Bus: Can not map completely, rest: %08x, addr %08x"					", twoLevelMMap.scnd_lvl_blockmask %08x blocksize %08x\n",mapsize,addr,twoLevelMMap.scnd_lvl_blockmask,twoLevelMMap.scnd_lvl_blocksize);				exit(3789);			}			return;		}                 if(pos>=devsize) {                        pos=0;                        mem=start_mem;                }                /* Special case 4GB */                if(!count) {                        return;                }        }}static voidMem_SplitLargePage(uint32_t pgaddr) {	uint32_t addr = pgaddr & ~MEM_MAP_BLOCKMASK;	int index=(addr>>MEM_MAP_SHIFT);	uint8_t *rhva = mem_map_read[index]; 	uint8_t *whva = mem_map_write[index];	uint8_t *hva = 0;	uint32_t slvl_size =  twoLevelMMap.scnd_lvl_blocksize;	int flags;	int count;	flags = 0;	if(!rhva && ! whva) {		/* nothing to split */		return;	}	if((rhva != whva) && (rhva !=0) && (whva !=0)) {		fprintf(stderr,"Can not split page with different read/write addresses\n");		return;	}	if(rhva) {		flags |= MEM_FLAG_READABLE;		hva = rhva;	} 	if(whva) {		flags |= MEM_FLAG_WRITABLE;		hva = whva;	}	if(!Mem_UnMapBlock(addr)) {		fprintf(stderr,"Failed to unmap block at %08x\n",addr);		}	for(count=0;count < MEM_MAP_BLOCKSIZE;count+=slvl_size) {		Mem_Map2LvlBlock(addr+count,hva+count,flags); 	}}voidMem_TracePage(uint32_t pgaddr) {	int index;	uint8_t *hva;	uint8_t **slvl_map;	Mem_SplitLargePage(pgaddr);	index = pgaddr >> twoLevelMMap.frst_lvl_shift; 	if(unlikely(!(slvl_map = twoLevelMMap.flvlmap_write[index]))) {		fprintf(stderr,"no slvl map for addr %08x\n",pgaddr); // jk		return;	}	index = (pgaddr & twoLevelMMap.scnd_lvl_mask) >> twoLevelMMap.scnd_lvl_shift;	hva = slvl_map[index];	if(hva && !((unsigned long)hva & PG_TRACED)) {				slvl_map[index] += PG_TRACED;	} else {		fprintf(stderr,"Page is already traced %08x hva %p %08x\n",pgaddr,hva,!((unsigned long)hva & PG_TRACED));	}	if(InvalidateProc) {		InvalidateProc();	}}voidMem_UntracePage(uint32_t pgaddr) {	int index;	uint8_t *hva;	uint8_t **slvl_map;	index = pgaddr >> twoLevelMMap.frst_lvl_shift; 	if(unlikely(!(slvl_map = twoLevelMMap.flvlmap_write[index]))) {		fprintf(stderr,"no slvl map for addr %08x\n",pgaddr); // jk		return;	}	index = (pgaddr & twoLevelMMap.scnd_lvl_mask) >> twoLevelMMap.scnd_lvl_shift;	hva = slvl_map[index];	if(hva && ((unsigned long)hva & PG_TRACED)) {		slvl_map[index] -= PG_TRACED;		//fprintf(stderr,"Untraced page at %08x, hva %p\n",pgaddr,slvl_map[index]);	} else {		fprintf(stderr,"Page was not traced %08x, hva %p\n",pgaddr,slvl_map[index]);	}	if(InvalidateProc) {		InvalidateProc();	}}void Mem_TraceRegion(uint32_t start,uint32_t length) {	uint32_t i;	int slvl_size =  twoLevelMMap.scnd_lvl_blocksize;	fprintf(stderr,"Trace region from %08x length %08x\n",start,length); // jk	for(i=0;i<length;i+=slvl_size) {		Mem_TracePage(start+i);	} }void Mem_UntraceRegion(uint32_t start,uint32_t length) {	uint32_t i;	int slvl_size =  twoLevelMMap.scnd_lvl_blocksize;	fprintf(stderr,"Untrace region from %08x length %08x\n",start,length); // jk	for(i=0;i<length;i+=slvl_size) {		Mem_UntracePage(start+i);	} }/* * -------------------------------------------------------------------- * Take existing mapping and split up a range from large pages * into small pages. * address may not wrap and size may not be 4G * -------------------------------------------------------------------- */voidMem_SplitLargePages(uint32_t start,uint32_t size) {	uint32_t addr = start & ~MEM_MAP_BLOCKMASK;	do {		Mem_SplitLargePage(addr); 		addr += MEM_MAP_BLOCKSIZE;			} while((addr-start) < size);}/* * --------------------------------------------------------------------------------- * UnMap a range *	This function may only called by device emulators in response to *	an unmap request.  * --------------------------------------------------------------------------------- */ voidMem_UnMapRange(uint32_t base,uint32_t mapsize) {        uint32_t addr;        uint32_t count=0;        for(addr=base;1;) {		if((mapsize>=MEM_MAP_BLOCKSIZE) && !(addr & MEM_MAP_BLOCKMASK)) {			if(Mem_UnMapBlock(addr) > 0) {				count+=MEM_MAP_BLOCKSIZE;				addr+=MEM_MAP_BLOCKSIZE;				mapsize-=MEM_MAP_BLOCKSIZE;			} else {				Mem_UnMap2LvlBlock(addr);				count+=twoLevelMMap.scnd_lvl_blocksize;				addr+=twoLevelMMap.scnd_lvl_blocksize;				mapsize-=twoLevelMMap.scnd_lvl_blocksize;			}		} else if((mapsize >= twoLevelMMap.scnd_lvl_blocksize) && !(addr & twoLevelMMap.scnd_lvl_blockmask)) {			Mem_UnMap2LvlBlock(addr);			count+=twoLevelMMap.scnd_lvl_blocksize;			addr+=twoLevelMMap.scnd_lvl_blocksize;			mapsize-=twoLevelMMap.scnd_lvl_blocksize;		} else {			return;		}                 /* Special case 4GB */                if(!count) {                        return;                }        }}void Mem_AreaDeleteMappings(BusDevice *bdev) {	while(bdev->first_mapping) {		MemMapping *mapping=bdev->first_mapping;		bdev->UnMap(bdev->owner,mapping->base,mapping->mapsize);		bdev->first_mapping=mapping->next;		free(mapping);	}        /* Need to Invalidate Tlb because we cache Host Virtual Addresses */	if(InvalidateProc) {		InvalidateProc();	}}/* * ---------------------------------------------------------------------- * Update Mappings is called by a chip emulator whenever it changes * its memory map by itself * ---------------------------------------------------------------------- */void Mem_AreaUpdateMappings(BusDevice *bdev) {	MemMapping *cursor;	/* First do a total Cleanup then map again */ 	for(cursor=bdev->first_mapping; cursor; cursor=cursor->next) {		bdev->UnMap(bdev->owner,cursor->base,cursor->mapsize);	}	for(cursor=bdev->first_mapping; cursor; cursor=cursor->next) {		bdev->Map(bdev->owner,cursor->base,cursor->mapsize,cursor->flags);	}        /* Need to Invalidate Tlb because we cache Host Virtual Addresses */	if(InvalidateProc) {		InvalidateProc();	}}/* * ------------------------------- * IO-Handling * ------------------------------- */#define IOH_HASH(addr) ((addr) + ((addr)>>18))&IOH_HASH_MASKIOHandler *IOH_Find(uint32_t address) {	IOHandler *cursor;	IOHandler **slvl_map;	uint32_t hash=IOH_HASH(address);	uint32_t index;	for(cursor=iohandlerHash[hash];cursor;cursor=cursor->next) {		if(cursor->cpu_addr==address) {			return cursor;		}	}	index=(address>>IOH_MAP_SHIFT);	if(iohandlerMap[index]) {		return (iohandlerMap[index]);	}	index = (address>>IOH_FLVL_SHIFT);	if((slvl_map = iohandlerFlvlMap[index])) {		index = (address & IOH_SLVL_MASK) >> IOH_SLVL_SHIFT;				return slvl_map[index];	} 	return NULL;}IOHandler *IOH_HashFind(uint32_t address) {	IOHandler *cursor;	uint32_t hash=IOH_HASH(address);	for(cursor=iohandlerHash[hash];cursor;cursor=cursor->next) {		if(cursor->cpu_addr==address) {			return cursor;		}	}	return NULL;}static voidIOH_New(uint32_t cpu_addr,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData,int len,uint32_t flags) {	uint32_t hash;	IOHandler *h;	int swap_endian;	int byteorder;	if(flags & IOH_FLG_BIG_ENDIAN) {		byteorder = en_BIG_ENDIAN;	} else if(flags & IOH_FLG_HOST_ENDIAN) {		byteorder = HOST_BYTEORDER;	} else {		byteorder = en_LITTLE_ENDIAN;	}	if(byteorder != HOST_BYTEORDER) {		swap_endian=1;	} else {		swap_endian=0;	}	if(IOH_HashFind(cpu_addr)) {		fprintf(stderr,"Bug, more than one IO-Handler for address %08x\n",cpu_addr);		exit(4324);	}	h=malloc(sizeof(IOHandler));	if(!h) {		perror("Out of memory allocating IOHandler\n");			exit(97);	}	memset(h,0,sizeof(IOHandler));	h->cpu_addr=cpu_addr;	h->clientData=clientData;	h->readproc=readproc;	h->writeproc=writeproc;	hash=IOH_HASH(cpu_addr);	h->next=iohandlerHash[hash];	h->swap_endian = swap_endian;	h->flags = flags;	h->len = len;	iohandlerHash[hash]=h;}voidIOH_New8f(uint32_t cpu_addr,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData,uint32_t flags) {	IOH_New(cpu_addr,readproc,writeproc,clientData,1,flags);}voidIOH_New16f(uint32_t cpu_addr,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData,uint32_t flags) {	if(flags & (IOH_FLG_PA_CBSE)) {		int i;		for(i=0;i<2;i++) {			IOH_New(cpu_addr+i,readproc,writeproc,clientData,2,flags); 		}	} else {		IOH_New(cpu_addr,readproc,writeproc,clientData,2,flags); 	}}voidIOH_New32f(uint32_t cpu_addr,IOReadProc *readproc,IOWriteProc *writeproc,void *clientData,uint32_t flags) {	/* Partial access: call base */	if(flags & IOH_FLG_PA_CBSE) {		int i;		for(i=0;i<4;i++) {			IOH_New(cpu_addr+i,readproc,writeproc,clientData,4,flags); 		}	} else {		IOH_New(cpu_addr,readproc,writeproc,clientData,4,flags); 	}}/* * ------------------------------------------------------------- * Allocate an iohandler and initialize the structure  * ------------------------------------------------------------- */static inline IOHandler *allocate_iohandler(uint32_t addr,IOReadProc *readproc,IOWriteProc *writeproc,int swap_endian,void *clientData) {	IOHandler *h;	h=malloc(sizeof(IOHandler));	if(!h) {		perror("Out of memory allocating IOHandler\n");			exit(97);	}	memset(h,0,sizeof(IOHandler));	h->cpu_addr=addr;	h->clientData=clientData;	h->readproc=readproc;	h->writeproc=writeproc;	h->next=NULL;	h->swap_endian = swap_endian;	return h;}static inline void IOH_MapBlock(uint32_t addr, IOHandler *h) {	uint32_t index=addr>>IOH_MAP_SHIFT;	if(iohandlerMap[index]) {		fprintf(stderr,"IO-Region %08x already allocated !\n",addr); 		exit(5342);	}	iohandlerMap[index]=h;}static inline voidIOH_Map2LvlBlock(uint32_t addr,IOHandler *h) {	IOHandler **sl_map;	int fl_index=addr>>IOH_FLVL_SHIFT;

⌨️ 快捷键说明

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