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

📄 memory.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
字号:
/**********************************//*                                *//*  Copyright 2000, David Grant   *//*                                *//*  see LICENSE for more details  *//*                                *//**********************************/#include <stdio.h>#include <stdlib.h>#include <string.h>/*#define TRACER_OFF*/#include "coldfire.h"/* longword - (msb) 3 2 1 0 (lsb) * Big endian: *   b3 b2 b1 b0  * Little endian: *   b0 b1 b2 b3 *//* External defs that need to be initialized */struct _memory_core memory_core;struct _SR *SRBits = (struct _SR *)&memory_core.sr;/* memory core copy with values used when reset */static struct _memory_core memory_core_reset_values;TRACER_DEFAULT_CHANNEL(memory);static struct _memory_module *memory_module = NULL;static int memory_module_count=0;static int memory_module_count_max=0;/* Make a list of pointers to segments.  Note: we don't make a list of segments *  directly, because some segments will want to save a pointer to themselves, *  and they can't do that if we're realloc()ing the list as we add more items. */struct _memory_segment_list_item {	struct _memory_segment *seg;};static struct _memory_segment_list_item *memory_segment_list = NULL;static int memory_segment_count=0;static int memory_segment_count_max=0;void memory_module_register(char *name, 		void (*setup)(struct _memory_segment *s)){	if(memory_module_count == memory_module_count_max) {		memory_module_count_max += 4;		memory_module = realloc(memory_module,					sizeof(struct _memory_module) * 						memory_module_count_max);	}	memory_module[memory_module_count].name = strdup(name);	memory_module[memory_module_count].setup = setup;	memory_module_count++;	}static unsigned int zero_register = 0;void memory_module_setup_segment(char *module_name, int base_register, int base, int len){	struct _memory_segment *s;	struct _memory_segment_list_item *i;	int x;	char movable = 1;		/* Setup the memory segment */	if(memory_segment_count == memory_segment_count_max) {		memory_segment_count_max += 4;		memory_segment_list = realloc(memory_segment_list,					sizeof(struct _memory_segment_list_item) * 						memory_segment_count_max);	}	i = &memory_segment_list[memory_segment_count];	s = malloc(sizeof(struct _memory_segment));	i->seg = s;	memset(s, 0, sizeof(struct _memory_segment));	s->base = base;	s->base_register = base_register;	/* The mask is the inverted length 	 *   len 0x100 ==  mask FFFFFF00 */	s->mask = ~(len - 1);		/* Find the module, and run the module setup */	for(x=0;x<memory_module_count;x++) {		if(strcasecmp(memory_module[x].name, module_name) == 0) {			memory_module[x].setup(s);			break;		}	}	if(x==memory_module_count) {		/* Not found */		printf("Could not find module for [%s]\n", module_name);	}		/* See if everything above registerd a base address register, if not	 * then give it the zero address */	if(s->base_register == NULL) {		s->base_register = &zero_register;		movable=0;	}		printf("0x%08lx -> 0x%08lx  %s\n",			*s->base_register + s->base, 			*s->base_register + s->base + ~s->mask,			movable ? "(movable)" : "");		printf("  ");	fflush(stdout);	memory_segment_count++;}struct _memory_segment *memory_find_segment_for(unsigned int offset){	int x;	struct _memory_segment_list_item *i;	for(x=0,i=&memory_segment_list[0];x<memory_segment_count;x++,i++) {		/* FIXME: optimize this by pre-calculation */		struct _memory_segment *s = i->seg;		register unsigned int b = *s->base_register + s->base;		if( (offset & s->mask) == b) {			return s;		}	}	return NULL;}static void memory_core_reset(void){	/* resetore default values */	memory_core.pc_instruction_begin = 0x0;	memory_core.sr = memory_core_reset_values.sr;	memory_core.vbr = memory_core_reset_values.vbr;	memory_core.mbar = memory_core_reset_values.mbar;	memory_core.rambar = memory_core_reset_values.rambar;	memory_core.rombar = memory_core_reset_values.rombar;	memory_core.pc = memory_core_reset_values.pc;	memory_core.a[7] = memory_core_reset_values.a[7] & 0xFFFFFFF0;}void memory_core_set_reset_values(char *s){	int argc;	char *argv[16];	int x;	struct _reg{		char *name;		unsigned int *ptr;	} regs[] = {		{ "mbar", &memory_core_reset_values.mbar },		{ "rombar", &memory_core_reset_values.rombar },		{ "rambar", &memory_core_reset_values.rambar },		{ "vbr", &memory_core_reset_values.vbr },		{ "sr", &memory_core_reset_values.sr },		{ "pc", &memory_core_reset_values.pc },		{ "sp", &memory_core_reset_values.a[7] },		{ NULL, NULL }};		for(x=0;x<argc;x+=2) {		unsigned int value;		int i;		sscanf(argv[x+1], "%lx", &value);		for(i=0; regs[i].name != NULL; i++) {			if(strcasecmp(argv[x], regs[i].name) == 0) {				*(regs[i].ptr) = value;			}		}	}}void memory_reset(void){	int x;	struct _memory_segment_list_item *i;	memory_core_reset();	/* Write the rombar to the entries in the vector table  */	for(x=0;x<256;x++)		Memory_Stor(32, (x*4)+memory_core.vbr, memory_core.rombar);		for(x=0,i=&memory_segment_list[0];x<memory_segment_count;x++,i++) {		struct _memory_segment *s = i->seg;		if(s->reset) s->reset(s);	}#if 0	TRACE("finding memory length\n");	/* Detect the length of the memory */	x = ;	while(1) {		x += 0x100;		if(!memory_seek(x)) {			break;		}	}	TRACE("length=0x%08lx\n", x);	/* Start A7 pointing aligned at the end of memory */	memory_core.a[7]=(x & 0xFFFFFFF0) -4;#endif	/* Fill out the values of the PC and the SP in the vector table */	Memory_Stor(32, memory_core.vbr, memory_core.a[7]);	Memory_Stor(32, memory_core.vbr+4, memory_core.pc);}void Memory_Init(void){	/* First reset the core, this just sets the core regsters, useful	 * because the modules depend on some of the core registers, like	 * the rombar and the mbar (just so they print properly) */	memory_core_reset();		printf("Loading memory modules...\n");	ram_init();	/*	timer_5206_init();	serial_5206_init();	sim_5206_init();	sim_5307_init();	isa_init();	*/}void Memory_DeInit(void){	int x;	struct _memory_segment_list_item *i;	for(x=0,i=&memory_segment_list[0];x<memory_segment_count;x++,i++) {		struct _memory_segment *s = i->seg;		s->fini(s);		if(s->code) free(s->code);		free(s);				}	free(memory_segment_list);}/* See if we can seek to address at offset */char memory_seek(unsigned int offset){	struct _memory_segment *s;		s = memory_find_segment_for(offset);		return (s==NULL) ? 0 : 1;}/*    Desc: Retrieves a value from the memory * Returns: 1 if successful, 0 if something bad happened  *   Notes: This always first retrieves a long into *Result, then it trims it down */char Memory_Retr(unsigned int *Result, short Size, int Offset){	struct _memory_segment *s;	unsigned int base_offset;		s = memory_find_segment_for(Offset);	if(s) {		base_offset = (unsigned int)Offset - 					(*s->base_register + s->base);		/* base_offset = (unsigned int)Offset & ~(s->base); */		return s->read(s, Result, Size, base_offset);	}	else{                if(Offset >= memory_core.mbar && Offset < (memory_core.mbar + memory_core.mbar_size))                        return memory_core.mbar_read(Result, Size, (Offset - memory_core.mbar));                if(Offset >= memory_core.mbar2 && Offset < (memory_core.mbar2 + memory_core.mbar2_size))                        return memory_core.mbar2_read(Result, Size, (Offset - memory_core.mbar2));        }	/* Coulnd't find it in the tables */	printf("retr retr failed for size=%d, offset=0x%08lx, pc=0x%x\n", Size, Offset, memory_core.pc);	skyeye_exit(1);	return 0;}char Memory_Stor(short Size, int Offset, unsigned int Value){	struct _memory_segment *s;	unsigned int base_offset;	/* Value will be in whatever endianness the computer is */	s = memory_find_segment_for(Offset);	if(s) {		base_offset = (unsigned int)Offset - 			(*s->base_register + s->base);		/* base_offset = (unsigned int)Offset & ~(s->base); */		return s->write(s, Size, base_offset, Value);	}	else{		if(Offset >= memory_core.mbar && Offset < (memory_core.mbar + memory_core.mbar_size))			return memory_core.mbar_write(Size, (Offset - memory_core.mbar), Value);		if(Offset >= memory_core.mbar2 && Offset < (memory_core.mbar2 + memory_core.mbar2_size))			return memory_core.mbar2_write(Size, (Offset - memory_core.mbar2),  Value);	}		/* Exception 2, access error */	printf("retr stor failed for size=%d, offset=0x%08lx, pc=0x%x\n", Size, Offset, memory_core.pc);	skyeye_exit(1);	return 0;}char Memory_RetrFromPC(unsigned int *Result, short Size){	char ReturnValue;	switch(Size) {	case 32:		ReturnValue = Memory_Retr(Result, 32, memory_core.pc);		memory_core.pc+=4;		return ReturnValue;	case 16:		ReturnValue = Memory_Retr(Result, 16, memory_core.pc);		memory_core.pc+=2;		return ReturnValue;	case 8:		memory_core.pc+=1;	/* Skip the first byte */		ReturnValue = Memory_Retr(Result, 8, memory_core.pc);		memory_core.pc+=1;	/* Go past the byte we just read */		return ReturnValue;	}	return 0;}void memory_update(void){	int x;	struct _memory_segment_list_item *i;	for(x=0, i=&memory_segment_list[0];x<memory_segment_count;x++,i++) {		struct _memory_segment *s = i->seg;		if(s->update) s->update(s);	}}void memory_dump_segments(void){	int x;	struct _memory_segment_list_item *i;	for(x=0, i=&memory_segment_list[0];x<memory_segment_count;x++,i++) {		struct _memory_segment *s = i->seg;		printf("%s: @%p, base_reg=%p, base=0x%08lx, data=%p\n",				s->name, s, s->base_register, s->base, s->data);	}}

⌨️ 快捷键说明

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