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

📄 board_ep7312.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/Board_EP7312.cpp
*
*  $Id: Board_EP7312.cpp,v 1.4 2005/06/16 11:26:48 qilj Exp $
*
*  \author  Lingjie Qi <lingjie_qi@163.com> 
                    zhao jun <junzhao_china@yahoo.com.cn>
*/
//=============================================================================
#include "./Board_EP7312.h"
#include "Processor_720T.h"

#include "Core/System.h"
#include "Core/Memory.h"
#include "Core/Helper.h"
#include "Core/ConfigFile.h"


#include "Device/UART_EP7312/UART_EP7312.h"
#include "Device/LCDDevice/LCD_Device.h"

#include <cstdio>
#include <fstream>
#include "iostream"
#include<io.h>
#include "Core/Observer.h"

namespace ARM
{
	bool Board_EP7312::load_fs(std::string name, Core::u32 addr)
	{
		std::string filepath = Core::Host_Machine::gen_fullpath(Core::Host_Machine::get_image_path("ARM"), name);
		std::ifstream fs((const char *)filepath.c_str(), std::ios::binary);
		if (fs.fail())
		{
			return false;
		}

		Core::Bytecode_Type buffer;
		char ch;
		while(fs.get(ch))
		{
			buffer.push_back(ch);
		}
		CPU_720T *cpu =  (CPU_720T *)Core::Wukong_Get_System().get_cpu();
		cpu->get_mmu().access(Core::Memory_32Bit::MEMORY_WRITE, addr, buffer.size(), buffer);

		return true;
	}

	void Board_EP7312::on_reset()
	{
		uart_ = (Core::Device<Core::u32> *) (Core::Wukong_Get_System().get_device("UART_EP7312"));
		WUKONG_ASSERT(uart_ != NULL);
		cpu_ = (CPU_720T *)Core::Wukong_Get_System().get_cpu();
		WUKONG_ASSERT(cpu_ != NULL);
		mmu_ = &((Core::MMU<Core::u32> &)cpu_->get_mmu());
		WUKONG_ASSERT(mmu_ != NULL);
		lcd_ = (Core::Device<Core::u32> *) (Core::Wukong_Get_System().get_device("LCD_"));
		//WUKONG_ASSERT(lcd_ != NULL);
		clock = 0xFFFF;
		io_prescale_ = 50;
		cpu_->set_exp_priority(CPU_720T::CPU_Interrupt::NO_exp);
		for(size_t i=0; i<Board_EP7312::Signal_End; ++i)
		{
			signal_[i] = 0;
		}
		int_reg_[INTSR1] = 0x1000;  // UART transmit FIFO empty interrupt
		int_reg_[INTMR1] = 0;
		sys_reg_[SYSCON1] = 0;
		sys_reg_[SYSFLG1] = 0x00400000;  // UART receiver FIFO empty 
		is_kb_input_ = false;
		tcd[0] = tcd [1] =0xfff;
		tcd_reload[0] = tcd_reload[1] = 0xfff;
		tc_prescale = 50;
	}

	void Board_EP7312::on_destroy()
	{
		if(uart_ != NULL)
			delete uart_;
	}

	bool Board_EP7312::prepare_rom(void)
	{
		std::string arch_name = Core::Wukong_Get_System().get_arch_name();
		std::string conf_file = Core::Wukong_Get_System().get_conf_name();
		std::string kernel_name = "";
		std::string fs_name = "";
		Core::u32 fs_addr = 0;
		Core::Wukong_Get_System().load_config(arch_name, conf_file);
		Core::Config_File * cf = Core::Wukong_Get_System().get_config();
		cf->read("/kernel/name", kernel_name);
		cf->read("/filesystem/name", fs_name);
		cf->read("/filesystem/address", fs_addr);
		load_fs(fs_name, fs_addr);
		return true;
	}

	void Board_EP7312::on_create()
	{
		name_ = "EP7312(ARM720T)";
		Core::Board<Core::u32>::on_create();
	}

	Core::Memory_Result Board_EP7312::io_dispatch(Core::Memory_Access_Type type, Core::u32 start,   \
		size_t size, Core::Bytecode_Type & buffer)
	{
		switch(type)
		{
		case Core::Memory_32Bit::MEMORY_READ:
			return io_read_word(start, size, buffer);

		case Core::Memory_32Bit::MEMORY_WRITE:
			return io_write_word(start, size, buffer);

		default:
			return Core::Dummy_MMU<Core::u32>::MEMORY_ACCESS_VIOLATION;
		}
	}

	Core::Memory_Result Board_EP7312::io_read_word(Core::u32 start, size_t size, \
		Core::Bytecode_Type & buffer)
	{
		if(start >= 0x80000100 && start <= 0x80000840)
		{
			Core::u32 & uartdr = ((DEVICE::UART_EP7312 *)uart_)->get_uartdr() ;
			switch(start)
			{
			case 0x80000100: // SYSCON1
				Core::Wukong_Get_System().convert_to_bytecode(sys_reg_[SYSCON1], buffer);
				break;
			case 0x80000140: // SYSFLG1
				Core::Wukong_Get_System().convert_to_bytecode(sys_reg_[SYSFLG1], buffer);
				break;
			case 0x80000240: // INTSR1
				Core::Wukong_Get_System().convert_to_bytecode(int_reg_[INTSR1], buffer);			
				break;
			case 0x80000280: // INTMR1
				Core::Wukong_Get_System().convert_to_bytecode(int_reg_[INTMR1], buffer);
				break;
			case 0x800002c0: // LCDCON
				Core::Wukong_Get_System().convert_to_bytecode(lcd_reg_[LCDCON], buffer);
				break;
			case 0x80000300: // TC1D
				Core::Wukong_Get_System().convert_to_bytecode(tcd[0], buffer);
				break;
			case 0x80000340: // TC2D
				Core::Wukong_Get_System().convert_to_bytecode(tcd[1], buffer);
				break;
			case 0x80000480: // UARTDR1
				Core::Wukong_Get_System().convert_to_bytecode(uartdr, buffer);
				sys_reg_[SYSFLG1] |= 0x00400000;
				int_reg_[INTSR1] &= ~ 0x2000;
				set_external_interrupt();
				break;
			case 0x80000500: // SYNCIO
				Core::Wukong_Get_System().convert_to_bytecode((Core::u32)1, buffer);
				break;

				// ! write-only
			case 0x800005c0: //STFCLR
			case 0x80000600: //BLEOI
			case 0x80000640: //MCEOI
			case 0x80000680: // TEOI
			case 0x800006c0: // TC1EOI
			case 0x80000700: // TC2EOI
			case 0x80000740: // RTCEOI
			case 0x80000780: // UMSEOI
			case 0x800007c0: // COEOI
			case 0x80000800: // HALT
			case 0x80000840: // STDBY
				break;
			default:	
				return Core::Dummy_MMU<Core::u32>::MEMORY_IO_RW;
			}
		}
		else
		{
			return Core::Dummy_MMU<Core::u32>::MEMORY_IO_RW;
		}
		return Core::Dummy_MMU<Core::u32>::MEMORY_SUCCESSFUL;
	}

	Core::Memory_Result Board_EP7312::io_write_word(Core::u32 start, size_t size, Core::Bytecode_Type & buffer)
	{
		if(start >= 0x80000100 && start <= 0x80000700)
		{
			Core::u32 target = 0;
			Core::Wukong_Get_System().convert_from_bytecode(buffer, target);
			switch(start)
			{
			case  0x80000100: // SYSCON1
				sys_reg_[SYSCON1] = target;
				break;
			case 0x80000140: // SYSFLG1
				break;
			case 0x80000240: // INTSR1
				int_reg_[INTSR1] = target;
				break;
			case 0x80000280: // INTMR1
				int_reg_[INTMR1] = target;
				set_external_interrupt();
				break;
			case 0x800002c0: // LCDCON
				Core::u32 temp;
				temp = lcd_reg_[LCDCON];
				lcd_reg_[LCDCON] = target;
				if ( temp != target)
				{
					int width=0, height=0, depth=8;
					Core::u32  lcdcon = lcd_reg_[LCDCON];
					Core::u32  vbufsiz = lcdcon & VBUFSIZ;
					Core::u32  linelen = (lcdcon & LINELEN) >> LINELEN_SHIFT;
					width = (linelen + 1) * 16;
					height = (vbufsiz + 1) * 128 / depth / width;
					//compute_lcd(width, height, depth);

					Core::Observer * lcd_screen = Core::Wukong_Get_System().get_view_by_name("LCD_");

					 lcd_screen ->enable(width,height,depth);

					((DEVICE::LCD *)lcd_)->init_lcd(width, height, depth);
					((DEVICE::LCD *)lcd_)->malloc_fb(width*height);
					lcd_->set_addr(0xc0000000, 0xc0000000+ width*height*depth/8 -1);
					lcd_->set_enable(true);
					//((DEVICE::LCD *)lcd_)->set_addr(0xc0000000, 0xc0000000+ width*height*depth/8 -1);
					//((DEVICE::LCD *)lcd_)->set_enable(true);
					//					std::cout << "fb_size = " << fb_size  << std::endl;
				}
				break;
			case 0x80000300: // TC1D
				tcd[0] = tcd_reload[0] = target & 0xfff;
				break;
			case 0x80000340: // TC2D
				tcd[1] = tcd_reload[1] = target & 0xfff;
				break;
			case 0x80000480: // UARTDR1
				uart_->on_mapped_memory_write(start, size, buffer);
				break;
			case 0x800006c0: // TC1EOI
				int_reg_[INTSR1] &= ~0x100;
				set_external_interrupt();
				break;
			case 0x80000700: // TC2EOI
				int_reg_[INTSR1] &= ~0x200;
				set_external_interrupt();
				break;

			default:	
				return Core::Dummy_MMU<Core::u32>::MEMORY_IO_RW;
			}
		}
		else
		{
			return Core::Dummy_MMU<Core::u32>::MEMORY_IO_RW;
		}
		return Core::Dummy_MMU<Core::u32>::MEMORY_SUCCESSFUL;
	}

	void Board_EP7312::io_do_cycle(void)
	{
		descend_io_prescale();
		if(test_io_prescale())
		{
			Core::u32 & uartdr = ((DEVICE::UART_EP7312 *)uart_)->get_uartdr();
			reset_io_prescale();		
			if(is_kb_input())
			{
				is_kb_input_ = true;
				char buf;
				Core::s32 n = kb_read(0, &buf, 1); 
				if (n) 
				{
					uartdr = (Core::u32)buf;
				}
			}
		}
	}

	Core::Interrupt_Type Board_EP7312::get_highest_interrupt(void)
	{
		descend_clock();

		if(is_kb_input_)
		{
			is_kb_input_ = false;
			return Board_EP7312::UXINT_sig;
		}
		else if( tc_prescale == 0 )
		{
			reset_clock();
			return Board_EP7312::CLOCK_INT;
		}
		else
		{
			//clock--;
			set_signal(Board_EP7312::IRQ_sig, false);
			return Inter_Undefined;
		}
	}

	void Board_EP7312::on_interrupt(Core::Interrupt_Type type)
	{
		int t;
		switch(type)
		{
		case Board_EP7312::CLOCK_INT:
			for (t = 0; t < 2; t++) 
			{
				if (tcd[t] == 0) 
				{
					if (sys_reg_[SYSCON1] & (t ? 0x40 : 0x10)) 
					{

						tcd[t] = tcd_reload[t];
					} else
					{
						tcd[t] = 0xffff;
					}
					int_reg_[INTSR1] |= (t ? 0x200 : 0x100);
					if(int_reg_[INTMR1] >> 8 ||int_reg_[INTMR1] >> 9 )
						signal_[IRQ_sig] = true;
				} else 
				{
					tcd[t]--;
				}
			}
			break;
		case Board_EP7312::UXINT_sig:
			sys_reg_[SYSFLG1] &= ~0x00400000;
			int_reg_[INTSR1] |= 0x2000;
			if(int_reg_[INTMR1] >> 13)
				signal_[IRQ_sig] = true;
			break;

		default:
			//	signal_[IRQ_sig] = false;
			break;
		}
	}

	void Board_EP7312::poll_extern_exception()
	{

		Core::Register &cpsr = cpu_->get_cpsr();
		CPU_720T::CPU_Interrupt current_exp_priority = cpu_->get_exp_priority();

		if(current_exp_priority > 3 || current_exp_priority < 0)
		{
			if( test_signal(Board_EP7312::FIQ_sig)		\
				&& !cpsr.test(6) )
			{
				cpu_->do_exception(CPU_720T::FIQ_exp);
				set_signal(Board_EP7312::FIQ_sig, false);
			}
		}
		if(current_exp_priority > 4 || current_exp_priority < 0)
		{
			if( test_signal(Board_EP7312::IRQ_sig)     \
				&& !cpsr.test(7) )
			{
				cpu_->do_exception(CPU_720T::IRQ_exp);
				set_signal(Board_EP7312::IRQ_sig, false);
			}
		}
	}

#ifdef LINUX
	Core::s32 Board_EP7312::kb_input()
	{
		fd_set rfds;
		struct timeval tv;
		FD_ZERO(&rfds);
		FD_SET(0, &rfds);
		tv.tv_sec = 0;
		tv.tv_usec = 0;
		return select(0+1, &rfds, NULL, NULL, &tv) ;
	}
#endif

#ifdef WIN32 
	Core::s32 Board_EP7312::kb_read(Core::s32 fd,char *buffer, Core::s32 count)
	{
		size_t size = Core::Wukong_Get_System().get_key_event_count();
		if (size == 0)
			return 0;

		for (size_t i = 0; (i < size) &&( i < count); ++i)
		{
			Core::System::Key_Event evt = Core::Wukong_Get_System().top_key_event();
			Core::Wukong_Get_System().pop_key_event();
			buffer[i] = (char)evt.keycode;
			if( buffer[i] == '\r')
				buffer[i] = '\n';
		}
		return i;

		/*Core::u32 i;
		for( i = 0; (i< count) && kbhit(); i++)
		{
		//			WUKONG_STDOUT<<"_"<<std::endl;
		buffer[i] = getch();
		//buffer[i] = fgetc(stdin);
		if( buffer[i] == '\r')
		buffer[i] = '\n';
		}
		return i;*/

	}

#endif

}

⌨️ 快捷键说明

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