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

📄 memory.c

📁 体系机构仿真
💻 C
字号:
/* * memory.c - flat memory space routines * * This file is an adaptation of the software in the SimpleScalar tool suite * originally written by Todd M. Austin for the Multiscalar Research Project * at the University of Wisconsin-Madison. * * The modifications were made by Naraig Manjikian at Queen's University, * Kingston, Ontario, Canada. * * The remainder of this header comment is unchanged from the original text. * *.......................................................................... *  * Copyright (C) 1994, 1995, 1996, 1997 by Todd M. Austin * * This source file is distributed "as is" in the hope that it will be * useful.  The tool set comes with no warranty, and no author or * distributor accepts any responsibility for the consequences of its * use.  *  * Everyone is granted permission to copy, modify and redistribute * this tool set under the following conditions: *  *    This source code is distributed for non-commercial use only.  *    Please contact the maintainer for restrictions applying to  *    commercial use. * *    Permission is granted to anyone to make or distribute copies *    of this source code, either as received or modified, in any *    medium, provided that all copyright notices, permission and *    nonwarranty notices are preserved, and that the distributor *    grants the recipient permission for further redistribution as *    permitted by this document. * *    Permission is granted to distribute this file in compiled *    or executable form under the same conditions that apply for *    source code, provided that either: * *    A. it is accompanied by the corresponding machine-readable *       source code, *    B. it is accompanied by a written offer, with no time limit, *       to give anyone a machine-readable copy of the corresponding *       source code in return for reimbursement of the cost of *       distribution.  This written offer must permit verbatim *       duplication by anyone, or *    C. it is distributed by someone who received only the *       executable form, and is accompanied by a copy of the *       written offer of source code that they received concurrently. * * In other words, you are welcome to use, share and improve this * source file.  You are forbidden to forbid anyone else to use, share * and improve what you give them. * * INTERNET: dburger@cs.wisc.edu * US Mail:  1210 W. Dayton Street, Madison, WI 53706 * * $Id: memory.c,v 1.5 1997/03/11 01:15:25 taustin Exp taustin $ * * $Log: memory.c,v $ * Revision 1.5  1997/03/11  01:15:25  taustin * updated copyright * mem_valid() added, indicates if an address is bogus, used by DLite! * long/int tweaks made for ALPHA target support * * Revision 1.4  1997/01/06  16:00:51  taustin * stat_reg calls now do not initialize stat variable values * * Revision 1.3  1996/12/27  15:52:46  taustin * updated comments * integrated support for options and stats packages * * Revision 1.1  1996/12/05  18:52:32  taustin * Initial revision * * */#include <stdio.h>#include <stdlib.h>#include "misc.h"#include "ss.h"#include "loader.h"#include "regs.h"#include "memory.h"/* top of the data segment */SS_ADDR_TYPE mem_brk_point = 0;/* lowest address accessed on the stack */SS_ADDR_TYPE mem_stack_min = 0x7fffffff;/* first level memory block table */char *mem_table[MEM_TABLE_SIZE];/* determines if the memory access is valid, returns error str or NULL */char *					/* error string, or NULL */mem_valid(enum mem_cmd cmd,		/* Read (from sim mem) or Write */	  SS_ADDR_TYPE addr,		/* target address to access */	  int nbytes,			/* number of bytes to access */	  int declare)			/* declare the error if detected? */{  char *err_str = NULL;  /* check alignments */  if ((nbytes & (nbytes-1)) != 0 || (addr & (nbytes-1)) != 0)    {      err_str = "bad size or alignment";    }  /* check permissions, no probes allowed into undefined segment regions */  else if (!(/* text access and a read */	   (addr >= ld_text_base && addr < (ld_text_base+ld_text_size)	    && cmd == Read)	   /* data access within bounds */	   || (addr >= ld_data_base && addr < ld_stack_base)))    {      err_str = "segmentation violation";    }  /* track the minimum SP for memory access stats */  if (addr > mem_brk_point && addr < mem_stack_min)    mem_stack_min = addr;  if (!declare)    return err_str;  else if (err_str != NULL)    fatal(err_str);  else /* no error */    return NULL;}/* generic memory access function, its safe because alignments and permissions   are checks, handles any resonable transfer size; note, bombs if nbytes   is larger then MEM_BLOCK_SIZE */voidmem_access(enum mem_cmd cmd,		/* Read (from sim mem) or Write */	   SS_ADDR_TYPE addr,		/* target address to access */	   void *vp,			/* host memory address to access */	   int nbytes)			/* number of bytes to access */{  char *p = vp;  /* check alignments */  if ((nbytes & (nbytes-1)) != 0 || (addr & (nbytes-1)) != 0)    fatal("access error: bad size or alignment, addr 0x%08x", addr);  /* check permissions, no probes allowed into undefined segment regions */  if (!(/* text access and a read */	(addr >= ld_text_base && addr < (ld_text_base+ld_text_size)	 && cmd == Read)	/* data access within bounds */	|| (addr >= ld_data_base && addr < ld_stack_base)))    fatal("access error: segmentation violation, addr 0x%08x", addr);  /* track the minimum SP for memory access stats */  if (addr > mem_brk_point && addr < mem_stack_min)    mem_stack_min = addr;  /* perform the copy */  switch (nbytes) {  case 1:    if (cmd == Read)      *((unsigned char *)p) = __MEM_READ_BYTE(addr);    else      __MEM_WRITE_BYTE(addr, *((unsigned char *)p));    break;  case 2:    if (cmd == Read)      *((unsigned short *)p) = __MEM_READ_HALF(addr);    else      __MEM_WRITE_HALF(addr, *((unsigned short *)p));    break;  case 4:    if (cmd == Read)      *((unsigned int *)p) = __MEM_READ_WORD(addr);    else      __MEM_WRITE_WORD(addr, *((unsigned int *)p));    break;  default:    {      /* nbytes >= 8 and power of two */      int words = nbytes >> 2;      if (cmd == Read)	{	  while (words-- > 0)	    {	      *((unsigned int *)p) = __MEM_READ_WORD(addr);	      p += 4;	      addr += 4;	    }	}      else	{	  while (words-- > 0)	    {	      __MEM_WRITE_WORD(addr, *((unsigned int *)p));	      p += 4;	      addr += 4;	    }	}    }    break;  }}/* allocate a memory block */char *mem_newblock(void){  /* see misc.c for details on the getcore() function */  return getcore(MEM_BLOCK_SIZE);}/* copy a '\0' terminated string through a memory access function, returns   the number of bytes copied, returns the number of bytes copied */intmem_strcpy(mem_access_fn mem_fn,	/* user-specified memory accessor */	   enum mem_cmd cmd,		/* Read (from sim mem) or Write */	   SS_ADDR_TYPE addr,		/* target address to access */	   char *s)			/* host memory string buffer */{  int n = 0;  char c;  switch (cmd) {  case Read:    /* copy until string terminator ('\0') is encountered */    do {      mem_fn(Read, addr++, &c, 1);      *s++ = c;      n++;    } while (c);    break;  case Write:    /* copy until string terminator ('\0') is encountered */    do {      c = *s++;      mem_fn(Write, addr++, &c, 1);      n++;    } while (c);    break;  default:    panic("bogus memory command");  }  return n;}/* copy NBYTES through a memory access function */voidmem_bcopy(mem_access_fn mem_fn,		/* user-specified memory accessor */	  enum mem_cmd cmd,		/* Read (from sim mem) or Write */	  SS_ADDR_TYPE addr,		/* target address to access */	  void *vp,			/* host memory address to access */	  int nbytes)			/* number of bytes to access */{  char *p = vp;  /* copy NBYTES bytes of simulator memory */  while (nbytes-- > 0)    mem_fn(cmd, addr++, p++, 1);}/* copy NBYTES through a memory access function, NBYTES must be a multiple   of 4 bytes, this function is faster than mem_bcopy() */voidmem_bcopy4(mem_access_fn mem_fn,	/* user-specified memory accessor */	   enum mem_cmd cmd,		/* Read (from sim mem) or Write */	   SS_ADDR_TYPE addr,		/* target address to access */	   void *vp,			/* host memory address to access */	   int nbytes)			/* number of bytes to access */{  char *p = vp;  int words = nbytes >> 2;		/* note: nbytes % 2 == 0 is assumed */  while (words-- > 0)    mem_fn(cmd, addr += 4, p += 4, 4);}/* zero out NBYTES through a memory access function */voidmem_bzero(mem_access_fn mem_fn,		/* user-specified memory accessor */	  SS_ADDR_TYPE addr,		/* target address to access */	  int nbytes)			/* number of bytes to clear */{  char c = 0;  /* zero out NBYTES of simulator memory */  while (nbytes-- > 0)    mem_fn(Write, addr++, &c, 1);}/* register memory system-specific options */voidmem_reg_options(struct opt_odb_t *odb)	/* option data base */{  /* none currently */}/* check memory system-specific option values */voidmem_check_options(struct opt_odb_t *odb, int argc, char **argv){  /* nada */}/* register memory system-specific statistics */voidmem_reg_stats(struct stat_sdb_t *sdb){  stat_reg_uint(sdb, "mem_brk_point",		"data segment break point",		(unsigned int *)&mem_brk_point, mem_brk_point, "  0x%08x");  stat_reg_uint(sdb, "mem_stack_min",		"lowest address accessed in stack segment",		(unsigned int *)&mem_stack_min, mem_stack_min, "  0x%08x");  stat_reg_formula(sdb, "mem_total_data",		   "total bytes used in init/uninit data segment",		   "(ld_data_size + 1023) / 1024",		   "%11.0fk");  stat_reg_formula(sdb, "mem_total_heap",		   "total bytes used in program heap segment",		   "(((mem_brk_point - (ld_data_base + ld_data_size)))+1023)"		   " / 1024", "%11.0fk");  stat_reg_formula(sdb, "mem_total_stack",		   "total bytes used in stack segment",		   "((ld_stack_base - mem_stack_min) + 1024) / 1024",		   "%11.0fk");  stat_reg_formula(sdb, "mem_total_mem",		   "total bytes used in data, heap, and stack segments",		   "mem_total_data + mem_total_heap + mem_total_stack",		   "%11.0fk");}/* initialize memory system, call before loader.c */voidmem_init(void){  int i;  /* initialize the first level page table to all empty */  for (i=0; i<MEM_TABLE_SIZE; i++)    mem_table[i] = NULL;}/* initialize memory system, call after loader.c */voidmem_init1(void){  /* initialize the bottom of heap to top of data segment */  mem_brk_point = ROUND_UP(ld_data_base + ld_data_size, SS_PAGE_SIZE);  /* set initial minimum stack pointer value to initial stack value */  mem_stack_min = regs_R[0][SS_STACK_REGNO];	/* pid 0 is first to start */}/* print out memory system configuration */voidmem_aux_config(FILE *stream)	/* output stream */{  /* none currently */}/* dump memory system stats */voidmem_aux_stats(FILE *stream)	/* output stream */{  /* zippo */}/* dump a block of memory */voidmem_dump(mem_access_fn mem_fn,		/* user-specified memory access */	 SS_ADDR_TYPE addr,		/* target address to dump */	 int len,			/* number bytes to dump */	 FILE *stream)			/* output stream */{  int data;  if (!stream)    stream = stderr;  addr &= sizeof(int);  len = (len+(sizeof(int)-1)) & sizeof(int);  while (len-- > 0)    {      mem_fn(Read, addr, &data, sizeof(int));      fprintf(stream, "0x%08x: %08x\n", addr, data);      addr += sizeof(int);    }}

⌨️ 快捷键说明

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