📄 memory.c
字号:
myfprintf(stream, "0x%08p: %08x\n", addr, data); addr += sizeof(word_t); } /* no faults... */ return md_fault_none;}/* copy a '\0' terminated string to/from simulated memory space, returns the number of bytes copied, returns any fault encountered */enum md_fault_typemem_strcpy(mem_access_fn mem_fn, /* user-specified memory accessor */ struct mem_t *mem, /* memory space to access */ enum mem_cmd cmd, /* Read (from sim mem) or Write */ md_addr_t addr, /* target address to access */ char *s){ int n = 0; char c; enum md_fault_type fault; switch (cmd) { case Read: /* copy until string terminator ('\0') is encountered */ do { fault = mem_fn(mem, Read, addr++, &c, 1); if (fault != md_fault_none) return fault; *s++ = c; n++; } while (c); break; case Write: /* copy until string terminator ('\0') is encountered */ do { c = *s++; fault = mem_fn(mem, Write, addr++, &c, 1); if (fault != md_fault_none) return fault; n++; } while (c); break; default: return md_fault_internal; } /* no faults... */ return md_fault_none;}/* copy NBYTES to/from simulated memory space, returns any faults */enum md_fault_typemem_bcopy(mem_access_fn mem_fn, /* user-specified memory accessor */ struct mem_t *mem, /* memory space to access */ enum mem_cmd cmd, /* Read (from sim mem) or Write */ md_addr_t addr, /* target address to access */ void *vp, /* host memory address to access */ int nbytes){ byte_t *p = vp; enum md_fault_type fault; /* copy NBYTES bytes to/from simulator memory */ while (nbytes-- > 0) { fault = mem_fn(mem, cmd, addr++, p++, 1); if (fault != md_fault_none) return fault; } /* no faults... */ return md_fault_none;}/* copy NBYTES to/from simulated memory space, NBYTES must be a multiple of 4 bytes, this function is faster than mem_bcopy(), returns any faults encountered */enum md_fault_typemem_bcopy4(mem_access_fn mem_fn, /* user-specified memory accessor */ struct mem_t *mem, /* memory space to access */ enum mem_cmd cmd, /* Read (from sim mem) or Write */ md_addr_t addr, /* target address to access */ void *vp, /* host memory address to access */ int nbytes){ byte_t *p = vp; int words = nbytes >> 2; /* note: nbytes % 2 == 0 is assumed */ enum md_fault_type fault; while (words-- > 0) { fault = mem_fn(mem, cmd, addr, p, sizeof(word_t)); if (fault != md_fault_none) return fault; addr += sizeof(word_t); p += sizeof(word_t); } /* no faults... */ return md_fault_none;}/* zero out NBYTES of simulated memory, returns any faults encountered */enum md_fault_typemem_bzero(mem_access_fn mem_fn, /* user-specified memory accessor */ struct mem_t *mem, /* memory space to access */ md_addr_t addr, /* target address to access */ int nbytes){ byte_t c = 0; enum md_fault_type fault; /* zero out NBYTES of simulator memory */ while (nbytes-- > 0) { fault = mem_fn(mem, Write, addr++, &c, 1); if (fault != md_fault_none) return fault; } /* no faults... */ return md_fault_none;}#if 0/* * The SimpleScalar virtual memory address space is 2^31 bytes mapped from * 0x00000000 to 0x7fffffff. The upper 2^31 bytes are currently reserved for * future developments. The address space from 0x00000000 to 0x00400000 is * currently unused. The address space from 0x00400000 to 0x10000000 is used * to map the program text (code), although accessing any memory outside of * the defined program space causes an error to be declared. The address * space from 0x10000000 to "mem_brk_point" is used for the program data * segment. This section of the address space is initially set to contain the * initialized data segment and then the uninitialized data segment. * "mem_brk_point" then grows to higher memory when sbrk() is called to * service heap growth. The data segment can continue to expand until it * collides with the stack segment. The stack segment starts at 0x7fffc000 * and grows to lower memory as more stack space is allocated. Initially, * the stack contains program arguments and environment variables (see * loader.c for details on initial stack layout). The stack may continue to * expand to lower memory until it collides with the data segment. * * The SimpleScalar virtual memory address space is implemented with a * one level page table, where the first level table contains MEM_TABLE_SIZE * pointers to MEM_BLOCK_SIZE byte pages in the second level table. Pages * are allocated in MEM_BLOCK_SIZE size chunks when first accessed, the initial * value of page memory is all zero. * * Graphically, it all looks like this: * * Virtual Level 1 Host Memory Pages * Address Page (allocated as needed) * Space Table * 0x00000000 +----------+ +-+ +-------------------+ * | unused | | |----->| memory page (64k) | * 0x00400000 +----------+ +-+ +-------------------+ * | | | | * | text | +-+ * | | | | * 0x10000000 +----------+ +-+ * | | | | * | data seg | +-+ +-------------------+ * | | | |----->| memory page (64k) | * mem_brk_point +----------+ +-+ +-------------------+ * | | | | * | | +-+ * | | | | * regs_R[29] +----------+ +-+ * (stack ptr) | | | | * | stack | +-+ * | | | | * 0x7fffc000 +----------+ +-+ +-------------------+ * | unsed | | |----->| memory page (64k) | * 0x7fffffff +----------+ +-+ +-------------------+ *//* top of the data segment, sbrk() moves this to higher memory */extern SS_ADDR_TYPE mem_brk_point;/* lowest address accessed on the stack */extern SS_ADDR_TYPE mem_stack_min;/* * memory page table defs *//* memory indirect table size (upper mem is not used) */#define MEM_TABLE_SIZE 0x8000 /* was: 0x7fff */#ifndef HIDE_MEM_TABLE_DEF /* used by sim-fast.c *//* the level 1 page table map */extern char *mem_table[MEM_TABLE_SIZE];#endif /* HIDE_MEM_TABLE_DEF *//* memory block size, in bytes */#define MEM_BLOCK_SIZE 0x10000 /* 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%08p", addr); /* track the minimum SP for memory access stats */ if (addr > mem_brk_point && addr < mem_stack_min) mem_stack_min = addr;/* determines if the memory access is valid, returns error str or NULL */char * /* error string, or NULL */mem_valid(struct mem_t *mem, /* memory space to probe */ enum mem_cmd cmd, /* Read (from sim'ed mem) or Write */ md_addr_t addr, /* target address to access */ int nbytes, /* number of bytes to access */ int declare); /* declare any detected error? *//* 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;}/* 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[SS_STACK_REGNO];}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -