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

📄 arm_processor.cpp

📁 浙江大学的悟空嵌入式系统模拟器
💻 CPP
字号:
/*
*  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    Arch/ARM/ARM_Processor.cpp
*
*  $Id: ARM_Processor.cpp,v 1.2 2005/06/16 11:27:06 qilj Exp $
*
*  \author    zhao jun <junzhao_china@yahoo.com.cn>
                      Lingjie Qi <lingjie_qi@163.com> 
*/
//=============================================================================

#include "./ARM_Processor.h"
#include "Core/Memory.h"
#include "Compare.h"
#include "MMU.h"

namespace ARM{

	std::string ARM_CPU::reg_name_[(Core::u32)ARM_CPU::REG_END] = {
		"R0","R1","R2","R3",
			"R4","R5","R6","R7",
			"R8","R9","R10","R11",
			"R12","R13","R14","R15",
			"R8_fiq","R9_fiq","R10_fiq","R11_fiq",
			"R12_fiq","R13_fiq","R14_fiq",  
			"R13_irq","R14_irq",
			"R13_svc","R14_svc",
			"R13_abt","R14_abt",
			"R13_und","R14_unds",
			"CPSR",
			"SPSR_svc","SPSR_abt",
			"SPSR_und","SPSR_irq","SPSR_fiq"
	};

	ARM_CPU::ARM_CPU(Core::Instruction_Set & instr_set, Core::MMU<Core::u32> * mmu)
		: Core::CPU_32Bit(instr_set, mmu)
	{
		//set pc 
	}

	void ARM_CPU::on_create()
	{
		configurate(config_);
	}

	void ARM_CPU::load_register()
	{
		Core::u32 reg_count = (Core::u32)ARM_CPU::REG_END - 1;
		WUKONG_ASSERT(reg_count != 0);
		for(Core::u32 i =0; i<reg_count; ++i)
		{
			Core::Register_File::append_profile(config_.register_config, \
				ARM_CPU::reg_name_[i], Core::Register_File::REGISTER_32BIT); 
		}
	}

	Core::Instruction_Unit ARM_CPU::fetch_instruction(Core::u32 pc)
	{
		Core::u32 res;
		Core::Bytecode_Type buffer;

		if ( (get_mmu().access(Core::Memory_32Bit::MEMORY_READ, pc, 4, buffer)) == MMU::PAGE_TRANSLATION_FAULT)
		{
			this->on_prefetch_exception(); 
			factual_pc_ = pc;
			res = 0xFFFFFFFE ;
			return (Core::Instruction_Unit)res;
		}
		else
		     Core::Wukong_Get_System().convert_from_bytecode(buffer, res);

		factual_pc_ = pc;
		set_pc(pc+4);

		return (Core::Instruction_Unit)res;
	}

	void ARM_CPU::adjust_reg_idx(size_t &idx)
	{
		WUKONG_ASSERT(idx>=0 && idx <=15);
		switch(current_mode_)
		{
		case User:
			break;
		case Svc:
			if(idx >= 13 && idx <=14)
				idx += 12;
			break;
		case IRQ:
			if(idx >= 13 && idx <= 14)
				idx += 10;
			break;
		case FIQ:
			if(idx >= 8 && idx <= 14)
				idx += 8;
			break;
		case Sys:
			break;
		case Abt:
			if(idx >= 13 && idx <= 14)
				idx += 14;
			break;
		case Und:
			if(idx >=13 && idx <= 14)
				idx += 16;
			break;
		default:
			break;
		}
	}

	bool ARM_CPU::read_register(size_t idx, Core::Register_Int & val)
	{	
		adjust_reg_idx(idx);
		val = reg_file_->get_register(idx).convert_to_int();
		return true;		
	}

	bool ARM_CPU::read_user_register(size_t idx, Core::Register_Int & val)
	{	
		val = reg_file_->get_register(idx).convert_to_int();
		return true;		
	}

	bool ARM_CPU::write_register(size_t idx, Core::Register_Int val)
	{
		adjust_reg_idx(idx);
		Core::Register & reg = reg_file_->get_register(idx);
		reg.convert_from_int(val);
		return true;
	}

	bool ARM_CPU::write_user_register(size_t idx, Core::Register_Int val)
	{
		Core::Register & reg = reg_file_->get_register(idx);
		reg.convert_from_int(val);
		return true;
	}


	void ARM_CPU::do_exception(CPU_Interrupt exp)
	{
		//set current interrupt's priority
		this->current_exp_priority_ = exp;
		switch(exp)
		{
		case ARM_CPU::Rst_exp:
			on_reset_exception();
			break;
		case ARM_CPU::Undef_exp:
			on_undefined_instruction();
			break;
		case ARM_CPU::PreAbt_exp:
			on_prefetch_exception();
			break;
		case ARM_CPU::DataAbt_exp:
			on_dataabt_exception();
			break;
		case ARM_CPU::IRQ_exp:
			on_irq_exception();
			break;
		case ARM_CPU::FIQ_exp:
			on_fiq_exception();
			break;
		case ARM_CPU::SWI_exp:
			on_swi_exception();
			break;
		default:
			break;
		}
	}

	void ARM_CPU::run(void)
	{
		Core::Board_32Bit * board = (Core::Board_32Bit *) Core::Wukong_Get_System().get_board();
		assert(board);
		running_ = true;
		Core::Bytecode_Type buffer,buf;

		while(running_)
		{		
			board->poll_extern_exception();
			Core::Instruction_Unit binary = fetch_instruction(get_pc());

			if ( !(instr_set_.execute_instruction(binary)) )
			{
				on_undefined_instruction();
			}

			board->io_do_cycle();		
			Core::Interrupt_Type intrp = board->get_highest_interrupt();
			board->on_interrupt(intrp);
			
		}
	}

	ARM_Coprocessor * ARM_CPU::get_coprocessor(size_t index)
	{
		return (ARM_Coprocessor *)coprocessors_[index];
	}


	void ARM_CPU::debugging_run()
	{
		Core::Board_32Bit * board = (Core::Board_32Bit *) Core::Wukong_Get_System().get_board();
		assert(board);

		Core::Debugger * debugger = Core::Wukong_Get_System().get_debugger();
		assert(debugger);
		
		set_break(true);
		debugger->debug(*this);

		running_ = true;

		while(running_)
		{
			if (is_break()) continue;
			//todo
			board->poll_extern_exception();
			Core::Interrupt_Type intrp = board->get_highest_interrupt();
			board->on_interrupt(intrp);

			Core::Instruction_Unit binary = fetch_instruction(get_pc());
			if ( !(instr_set_.execute_instruction(binary)) )
			{
				on_undefined_instruction(binary);
			}
			
			if(con_)
			{
				con_ = false;
				if(current_bpt_.addr != -1)	
				{
					std::map<Core::u32, BreakPoint>::iterator pos;
					pos = bpt_map_.find(current_bpt_.addr);
					if( pos != bpt_map_.end() )
					{
						Core::Bytecode_Type buffer;
						Core::Wukong_Get_System().convert_to_bytecode(0xFFFFFFFF, buffer);
						get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, current_bpt_.addr, 4, buffer);
					}
					current_bpt_.addr = -1;
				}
			}
			if (is_single_step())
			{
				set_break(true);
				set_single_step(false);
				if(current_bpt_.addr != -1)
				{
					std::map<Core::u32, BreakPoint>::iterator pos;
					pos = bpt_map_.find(current_bpt_.addr);
					//WUKONG_ASSERT( pos = bpt_map_.end() );
					if( pos != bpt_map_.end() )
					{
						Core::Bytecode_Type buffer;
						Core::Wukong_Get_System().convert_to_bytecode(0xFFFFFFFF, buffer);
						get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, current_bpt_.addr, 4, buffer);
					}
					current_bpt_.addr = -1;
				}
			}

		}
	}

	Core::s32 ARM_CPU::insert_breakpoint(Core::Debugger::Breakpoint_Type btype,Core::u32 addr, size_t len)
	{
		Core::Bytecode_Type buffer;
		BreakPoint bp;
		bp.addr = addr;
		Core::u32 val = 0;
		
		get_mmu().access(Core::Memory_32Bit::MEMORY_READ, addr, len, buffer);

		Core::Wukong_Get_System().convert_from_bytecode(buffer, val);

		bp.res = buffer;
		Core::Wukong_Get_System().convert_to_bytecode(0xFFFFFFFF, buffer);
		get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, addr, len, buffer);
		switch(btype)
		{
		case Core::Debugger::MEMORY_BREAKPOINT:
			bp.btype = btype;
			break;
		case Core::Debugger::HARDWARE_BREAKPOINT:
			bp.btype = btype;
			break;
		case Core::Debugger::WRITE_WATCHPOINT:
			bp.btype = btype;
			break;
		case Core::Debugger::READ_WATCHPOINT:
			bp.btype = btype;
			break;
		case Core::Debugger::ACCESS_WATCHPOINT:
			bp.btype = btype;
			break;
		default:
			return -1;
		}
		if( val != 0xFFFFFFFF)
		{
			//set many breakpoint in address
			bpt_map_.insert(std::pair<Core::u32, BreakPoint>(addr, bp));
		}
		return addr;
	}

	Core::s32 ARM_CPU::remove_breakpoint(Core::Debugger::Breakpoint_Type btype,Core::u32 addr, size_t len)
	{
		std::map<Core::u32, BreakPoint>::iterator pos;
		pos = bpt_map_.find(addr);
		WUKONG_ASSERT( pos != bpt_map_.end() );
		get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, addr, len, bpt_map_[addr].res);
		bpt_map_.erase(pos);
		return addr;
	}

	void ARM_CPU::step_info()
	{
		if(current_bpt_.addr != -1)//jump last 1 instruction
		{
			set_pc(current_bpt_.addr);
			get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, current_bpt_.addr, 4, current_bpt_.res);
			//current_bpt_ = NULL;
		}
		set_single_step(true);
	}

	void ARM_CPU::step_over()
	{
	}

	void ARM_CPU::con()
	{
		if(current_bpt_.addr != -1)
		{
			set_pc(current_bpt_.addr);
			get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, current_bpt_.addr, 4, current_bpt_.res);
		}
		set_break(false);
		set_single_step(false);
		con_ = true;
	}

}

⌨️ 快捷键说明

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