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

📄 mmu.h

📁 浙江大学的悟空嵌入式系统模拟器
💻 H
字号:
/*
 *  Copyright (c) 2005 Zhejiang University, P.R.China
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */ 

//=============================================================================
/**
 *  \file    ARM/MMU.h
 *
 *  $Id: MMU.h,v 1.5 2005/06/15 12:50:42 jiajc Exp $
 *
 *  \author  Juncheng Jia <jiajuncheng@gmail.com>
 */
//=============================================================================

#ifndef ARM__MMU_H_INCLUDED
#define ARM__MMU_H_INCLUDED

#include "Core/Memory.h"
#include "Coprocessor.h"
#include "ARM_Processor.h"

using namespace Core;

namespace ARM { 

	class MMU;

	//! TLB
	class TLB
	{
	public:
		//! Mapping type
		typedef enum
		{
			TLB_INVALID = 0,	//!< fault
			TLB_SMALLPAGE = 1,	//!< smallpage
			TLB_LARGEPAGE = 2,	//!< largepage
			TLB_SECTION = 3,	//!< section
			TLB_TINYPAGE = 4	//!< extended smallpage
		} Mapping_Type;

		//! TLB entry 
		typedef struct
		{
			u32 va;	//!< virtual address
			u32 pa;	//!< physical address
			u32 perms;	//!< permssion bits
			u32 domain;	//!< domain number
			Mapping_Type mapping;	//!< mapping type
		} Entry;

		//! Domain access type
		typedef enum
		{
			NO_ACCESS,
			CLIENT,
			RESERVED,
			MANAGER
		} Domain_Access_Type;

		//! Masks for different mapping types
		static const u32 masks[];

		//! Ctor
		TLB(MMU & mmu, size_t size);

		//! Dtor
		~TLB();

		//! Check if the access is permitted
		Memory_Result check_access(u32 va, Entry * entry, bool is_read);

		//! Translation table walk
		Memory_Result ttw(u32 va, Entry ** tlb);

		//! Invalidate all the entries in TLB
		void invalidate_all();

		//! Invalidate a single entry
		void invalidate(u32 va);

		//! Search an entry by virtual address
		Entry *search(u32 va);

		//u32 cache_flag(Entry * entry);

		//u32 buffer_flag(Entry * entry);

		u32 get_pa(Entry * entry, u32 va);
	    	
		bool check_perms(int ap, bool is_read);

	protected:
		u32 cycle_;
		std::vector<Entry> entrys_;
		MMU & mmu_;
	};

	//! Cache
	class Cache
	{
	public:

		const static TAG_VALID_FLAG = 1;
		const static TAG_FIRST_HALF_DIRTY = 2;
		const static TAG_LAST_HALF_DIRTY	= 4;
		
		//! Write mode
		typedef enum
		{
			WRITE_BACK,
			WRITE_THROUGH
		} Write_Mode;

		//! Cache line 
		typedef struct
		{
			u32 tag;
			u32 pa;
			std::vector<u8> data;
		} Cache_Line;

		//! Cache set
		typedef struct
		{
			std::vector<Cache_Line> lines;
			u32 cycle;
		} Cache_Set;

		//! Ctor
		Cache(MMU & mmu, size_t width, size_t way, size_t set, Write_Mode  write_mode);

		//! Dtor
		~Cache();

		//! Search a cache line by virtual address
		Cache_Line * search(u32 va);

		//! Allocate a cache line
		Cache_Line * allocate(u32 va, u32 pa);

		//! Write a cache line back to memory
		void write_back(Cache_Line * cache);

		//! 
		void clean(u32 va);

		//! Invalidate a single cache line
		void invalidate(u32 va);

		//! Invalidate all cache line
		void invalidate_all();

		size_t get_set_index(u32 va);

		u32 get_tag(u32 va);

		size_t get_width();

		size_t get_way();

		size_t get_set();
			
	protected:
		size_t num_width_;
		size_t num_way_;
		size_t num_set_;
		Write_Mode write_mode_;
		std::vector<Cache_Set> sets_;
		MMU & mmu_;
	};

	//! MMU
	class MMU : public Core::MMU<u32>
	{
		friend TLB;
		friend Cache;
	public:
		//! constant for data read
		const static Memory_Access_Type DATA_READ = 0;
		//! constant for data write
		const static Memory_Access_Type DATA_WRITE = 1;
		//! constant for instruction read
		const static Memory_Access_Type INSTR_READ = 2; 

		const static WORD_SHT = 2;
		const static WORD_SIZE = 1 << WORD_SHT;

		//! Result for MMU access, compatible with Dummy_MMU
		const static Memory_Result ACCESS_SUCCESSFUL							= 0x0;
		const static Memory_Result ACCESS_FAULT									= 0x7;//0x1;
		const static Memory_Result IO_RW										= 0x3;

		//! constants for fault status
		const static u32 TERMINAL_EXCEPTION								= 0x2;
		const static u32 VECTOR_EXCEPTION								= 0x0;
		const static u32 ALIGNMENT_FAULT								= 0x1;
		const static u32 FIRST_LEVEL_EXTERNAL_ABORT_ON_TRANSLATION		= 0xC;
		const static u32 SECOND_LEVEL_EXTERNAL_ABORT_ON_TRANSLATION		= 0xE;
		const static u32 SECTION_TRANSLATION_FAULT						= 0x5;
		const static u32 PAGE_TRANSLATION_FAULT							= 0x7;
		const static u32 SECTION_DOMAIN_FAULT							= 0x9;
		const static u32 PAGE_DOMAIN_FAULT								= 0xB;
		const static u32 SECTION_PERMISSION_FAULT						= 0xD;
		const static u32 SUBPAGE_PERMISSION_FAULT						= 0xF;
		const static u32 SECTION_EXTERNAL_ABORT_ON_LINEFETCH			= 0x4;
		const static u32 PAGE_EXTERNAL_ABORT_ON_LINEFETCH				= 0x6;
		const static u32 SECTION_EXTERNAL_ABORT_ON_NON_LINEFETCH		= 0x8;
		const static u32 PAGE_EXTERNAL_ABORT_ON_NON_LINEFETCH			= 0xA;

		//! constant for Fast Context Switch Extension Mask
		const static u32 PID_MAP_MASK = 0xfe000000;

		//! Ctor
		MMU(void);

		//! Dtor
		virtual ~MMU(void) = 0;

		//! Access the memory through MMU
		virtual Memory_Result access(Memory_Access_Type type, u32 start, size_t size, Bytecode_Type & buffer);

	protected:
		//! Workhorse for MMU access
		virtual Memory_Result data_read(u32 start, size_t size, Bytecode_Type & buffer) = 0;
		virtual Memory_Result data_write(u32 start, size_t size, Bytecode_Type & buffer) = 0;
		virtual Memory_Result instr_read(u32 start, size_t size, Bytecode_Type & buffer) = 0;

		//! Wrapper for direct memory access
		Memory_Result mem_access(Memory_Access_Type type, u32 start, size_t size, Bytecode_Type & buffer);
		
		bool is_enable();

		void disable();

		void enable();

		bool system_protection_on();

		bool rom_protection_on();

		bool is_user_mode();

		TLB::Domain_Access_Type domain_access_type(u32 domain_num);

		void set_fault_status(u32 value);

		void set_fault_address(u32 value);

		u32 get_translation_table_base();

		bool align_fault_check_on();

		bool cache_on();

		CP15 * get_cp15();

		ARM_CPU * get_cpu();

	};


#include "./MMU_i.h"

} //namespace
#endif

⌨️ 快捷键说明

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