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

📄 emumem.h

📁 arm的模拟器
💻 H
📖 第 1 页 / 共 2 页
字号:
		memory_fault_t get_last_fault() const {return last_fault;}		target_addr_t  get_last_faddr() const {return last_faddr;}	private:		/* a page table entry */		typedef struct memory_page_table_entry_t		{			unsigned int flag;			byte_t *ptr;		} memory_page_table_entry_t;		// get the permission bits of a page		unsigned int get_page_permission(target_addr_t addr) const; 		void set_page_permission(target_addr_t addr, unsigned int perm);		// mark a page as available or unavailable		void mark_page_available(target_addr_t addr, unsigned int perm);		void mark_page_unavailable(target_addr_t addr);		// remap and unmap a page, page is unavailable after successful unmap		void remap_page(target_addr_t addr,						memory_ext_interface *mif, unsigned int perm);		void unmap_page(target_addr_t addr);		/* test if an address crosses page boundary, size < MEM_PAGE_SIZE */		bool cross_page_boundary(target_addr_t addr, unsigned int size) const		{			return (addr & (MEMORY_PAGE_SIZE - 1)) > (MEMORY_PAGE_SIZE - size);		}		/* some useful utilities */		target_addr_t align_to_page_boundary(target_addr_t addr) const		{			return addr & ~(MEMORY_PAGE_SIZE-1);		}		byte_t swap(byte_t val) const		{			return val;		}		hword_t swap(hword_t val) const		{			return (val>>8) | (val<<8);		}		word_t swap(word_t val) const		{			return (val>>24) | ((val>>8)&0xFF00) |				   ((val&0xFF00)<<8) | (val<<24) ;		}		dword_t swap(dword_t val) const		{			return ((dword_t)swap((word_t)val)<<32) |				    (dword_t)swap((word_t)(val>>32));		}		/* storage allocated for a normal page */		bool page_allocated(const memory_page_table_entry_t *pte) const 		{			return ((pte->flag & MEMORY_PAGE_SLOW)==0);		}		/* storage allocated for a normal page */		bool page_allocated(target_addr_t addr) const 		{			target_addr_t page_index = addr >> MEMORY_PAGE_SIZE_BITS;			return ((page_table[page_index].flag & MEMORY_PAGE_SLOW)==0);		}		/* page remapped */		bool page_remapped(const memory_page_table_entry_t *pte) const 		{			return (pte->flag & MEMORY_PAGE_REMAPPED);		}		/* page remapped */		bool page_remapped(target_addr_t addr) const 		{			target_addr_t page_index = addr >> MEMORY_PAGE_SIZE_BITS;			return (page_table[page_index].flag & MEMORY_PAGE_REMAPPED);		}		const memory_page_table_entry_t *get_page(target_addr_t addr) const		{			target_addr_t page_index = addr >> MEMORY_PAGE_SIZE_BITS;			return page_table + page_index;		}		memory_page_table_entry_t *get_page(target_addr_t addr)		{			target_addr_t page_index = addr >> MEMORY_PAGE_SIZE_BITS;			return page_table + page_index;		}		template<class T>		T read_base(target_addr_t addr)		{#ifdef CHECK_PAGE_BOUNDARY			/* if crossing page boundary */			if (sizeof(T) > 1 && cross_page_boundary(addr, sizeof(T)))				return read_slow<T>(addr);#endif			const memory_page_table_entry_t *pte = get_page(addr);			/* if empty (not allocated), remapped, bad, or not readable */			if (!(pte->flag & MEMORY_PAGE_READABLE))				return read_slow<T>(addr);#if WORDS_BIGENDIAN==TARGET_LITTLE_ENDIAN			return swap(*reinterpret_cast<T *>(pte->ptr + addr));#else			return *reinterpret_cast<T*>(pte->ptr + addr);#endif		}		template<class T>		memory_fault_t read_base(target_addr_t addr, T *pval)		{#ifdef CHECK_PAGE_BOUNDARY			/* if crossing page boundary */			if (sizeof(T) > 1 && cross_page_boundary(addr, sizeof(T)))				return read_slow(addr, pval);#endif			const memory_page_table_entry_t *pte = get_page(addr);			/* if empty (not allocated), remapped, bad, or not readable */			if (!(pte->flag & MEMORY_PAGE_READABLE))				return read_slow(addr, pval);#if WORDS_BIGENDIAN==TARGET_LITTLE_ENDIAN			*pval = swap(*reinterpret_cast<T *>(pte->ptr + addr));#else			*pval = *reinterpret_cast<T*>(pte->ptr + addr);#endif			return MEM_NO_FAULT;		}		template<class T>		memory_fault_t write_base(target_addr_t addr, T value)		{#ifdef CHECK_PAGE_BOUNDARY			/* if crossing page boundary */			if (cross_page_boundary(addr, sizeof(T)))				return write_slow(addr, value);#endif			const memory_page_table_entry_t *pte = get_page(addr);			/* if empty (not allocated), remapped, bad, or not writable */			if (!(pte->flag & MEMORY_PAGE_WRITABLE))				return write_slow(addr, value);#if WORDS_BIGENDIAN==TARGET_LITTLE_ENDIAN			*reinterpret_cast<T *>(pte->ptr + addr) = swap(value);#else			*reinterpret_cast<T *>(pte->ptr + addr) = value;#endif			return MEM_NO_FAULT;		}		/* slow but full featured memory acecss interface		 * overloading is safer here since these are private		 */		memory_fault_t write_slow(target_addr_t addr, dword_t value);		memory_fault_t write_slow(target_addr_t addr, word_t  value);		memory_fault_t write_slow(target_addr_t addr, hword_t value);		memory_fault_t write_slow(target_addr_t addr, byte_t  value);		memory_fault_t read_slow(target_addr_t addr, dword_t *pval);		memory_fault_t read_slow(target_addr_t addr, word_t  *pval);		memory_fault_t read_slow(target_addr_t addr, hword_t *pval);		memory_fault_t read_slow(target_addr_t addr, byte_t  *pval);		/* these are the basis of the above _slow functions,		 * their implementation is hidden in emumem.cpp file		 */		template <class T>		memory_fault_t read_slow_base(target_addr_t addr, T *pval);		template <class T>		memory_fault_t write_slow_base(target_addr_t addr, T val);		template <class T>		T read_slow(target_addr_t addr)		{			T val;			read_slow(addr, &val);			return val;		}		/* simple block access functions */		memory_fault_t read_block_within_page(void *buf,			target_addr_t addr, unsigned int size, unsigned *psize);		memory_fault_t write_block_within_page(void *buf,			target_addr_t addr, unsigned int size, unsigned *psize);		memory_fault_t set_block_within_page(target_addr_t addr,			byte_t value, unsigned int size, unsigned *psize);		/* allocate and free space for a page		 * when memory runs out, allocate_page returns NOMEMORY_FAULT		 */		memory_fault_t allocate_page(memory_page_table_entry_t *pte);		void free_page(memory_page_table_entry_t *pte);		/* returns non-zero if there is a permission fault */		memory_fault_t check_page_permission(target_addr_t addr,				unsigned int perm) const;		memory_fault_t check_page_permission				(const memory_page_table_entry_t *pte,				unsigned int perm) const;		/* Address translation, NULL if remapped or error.		 * The function is created for MMU's use.		 * The return value does not point to the actually storage.		 * Instead, ptr+addr is the actual address.		 * See allocate page for details.		 */		byte_t *translate(target_addr_t addr)		{			memory_fault_t fault;			memory_page_table_entry_t *pte = get_page(addr);			/* if normal */			if (page_allocated(pte)) return pte->ptr;			/* normal page without space */			if (pte->flag & MEMORY_PAGE_EMPTY) 			{				if ((fault = allocate_page(pte)) != MEM_NO_FAULT)					report_fault(fault, addr);				return pte->ptr; //ptr is NULL when allocate fails			}			/* IO remap, bad address */			return NULL;		}		/* report a fault, raise a signal it fault_sig is not -1 */		void report_fault(memory_fault_t f, target_addr_t addr);		/* page table */		memory_page_table_entry_t page_table[MEMORY_PAGE_TABLE_SIZE];		/* stats information */		unsigned int page_count;			/* signal on fault */		int fault_sig;		/* stores the information of the last fault*/		memory_fault_t last_fault;		target_addr_t last_faddr;		friend class arm_mmu;};} /* namespace simit */#endif

⌨️ 快捷键说明

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