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

📄 main.cc

📁 一个mips虚拟机非常好代码,使用C++来编写的,希望大家多学学,
💻 CC
字号:
//IDE bus master controler & slave device //Note that you should comment endian_fix() in io.h before using it//Rita <RitaShen@cse.unsw.edu.au>#include <stdio.h>#include <string.h>#include <unistd.h>#include <assert.hh>#include <checkpoint.hh>#include <device.hh>#include <inttypes.hh>#include <module.hh>#include <serial.hh>#include <simarg.hh>#include <sulima.hh>#include <sys/stat.h>#include "ide.hh"// Serialization information.//SerialType<IDE> IDE::type(       "IDE",    "Generic IDE Controller");// Runtime constructor.IDE::IDE(const SimArgs& args)   //since I am a device, so do nothing here, wait for driver//    : Module(args), PCIDevice(32, PCI_VENDOR_ID_DEC_IDE, PCI_DEVICE_ID_DEC_IDE, PCI_CLASS_IDE), file_name(0), data(0)     {	/*the 256 16-bit words are stored by 128 32-bit words, RitaShen*/	dev_words[31]=0x00000101; 	dev_words[41]=0x00004000; 	dev_words[30]=0x0000400;    //64M IDE	if (args.length() > 2)		throw Error("IDE device: Too many arguments to \"sim::install IDE\".");	define("fileName", conf.file_name);    	define("size", conf.size);    	define("readLatency", conf.read_latency, 150);    	define("writeLatency", conf.write_latency, 150);}// Serialized constructor.IDE::IDE(Checkpoint& cp)    : Module(cp), PCIDevice(32, PCI_VENDOR_ID_DEC_IDE, PCI_DEVICE_ID_DEC_IDE, PCI_CLASS_IDE), file_name(0), data(0)        {	    	define("fileName", conf.file_name, file_name);    	cp >> conf.size >> conf.read_latency >> conf.write_latency >> '\n';    	define("size", conf.size);    	define("readLatency", conf.read_latency, conf.read_latency);    	define("writeLatency", conf.write_latency, conf.write_latency);    	reset(false);}IDE::~IDE(){ 	delete file_name;    	delete data;}// Module interface.voidIDE::reset(bool warm){}// Serialization interface.voidIDE::checkpoint(Checkpoint& cp, bool parent) const{}voidIDE::init(Bus *b, InterruptSink *intc, UInt64 base_address, UInt64 size, int base_irq){	bus = b;        intctrl = intc;	irq=base_irq;        bar[0] = base_address | 1;	bar[1] = (base_address+8) | 1;	bar[2] = (base_address+10) | 1;	bar[3] = (base_address+18) | 1;	bar[4] = (base_address+20) | 1;	bar[5] = 0;}voidIDE::io_poll(){}ClockValueIDE::read(UInt64 addr, UInt64* buf, int size)              //what's size for??  //{		unsigned int reg;	reg= addr  & 0xff;    	UInt32 val;	switch (reg){		case 0:  //for 256 device words		dide_data.data=dev_words[words_counter];		words_counter=words_counter+1;		if (words_counter<128) 			dide_devcon.r.nien=1;		else {dide_stat.r.drq=0;		      dide_devcon.r.nien=0;		};			val=dide_data.data;		break;	case 1: /* error Register and feature */  		val = dide_err.data;		break;	case 2: /* Sec_Count */		val =dide_sectorcount.data;		break;	case 3: /* LBA_Low_Byte */		val = dide_lbal.data;		break;	case 4: /* LBA_Mid_Byte */		val = dide_lbam.data;		break;	case 5: /* LBA_High_Byte */		val = dide_lbah.data;		break;	case 6: /* Device regi */		val = dide_dev.data;		break;	case 7: val = dide_stat.data;		break;	case 8: val = dide_astat.data;		break;	case 20: /*bus master command regi*/		val = bmide_comm.data;			break;	case 22: /*bus master status regi*/	       	val = bmide_stat.data;  		break;	case 24: /*bus master PRD regi*/		val = bmide_dtpr.data;		break;		default:		log("IDE device Read unimplemented register %d\n", reg);		val = 0;		break;	}	*buf = val;		return 0; // ignore latency}ClockValue IDE::write(UInt64 addr, const UInt64* buf, int size){		unsigned int reg = addr & 0xff; 	UInt32 val;	val= *buf;	switch (reg)	{		case 0: /* data regi */		dide_data.data=val;		break;	case 1: /* error regi & feature Register */		dide_feature.data= val;	      	break;	case 2: /*Sec_Count*/		dide_sectorcount.data=val;		break;	case 4: /* LBA_Mid_Byte Register */		dide_lbam.data = val;		break;	case 3: /*LBA_Low_Byte*/		dide_lbal.data=val;		break;	case 5: /*  LBA_High_Byte */		dide_lbah.data = val;		break;	case 6: /* device regi */		 dide_dev.data= val;		break;	case 7: /* command Register & status Regi*/		dide_comm.data= val;		do_command(val);		break;	case 8: /* for alternate status & device control */		dide_devcon.data = val;		break;	case 20: /*bus master command regi*/		bmide_comm.data = val;		break;		case 22: /*bus master status, write 1 to clear Interrupr and error */		if (val & 0x04)			clear_interrupt();		bmide_stat.data = val & 0xf9;		break;	case 24: /*bus master PRD regi*/		bmide_dtpr.data =val;		break;	default:		log("IDE device: Write unimplemented register %d %x\n", reg, val);		break;	}		return 0; // ignore latency}void IDE::do_command(UInt16 code){		dide_stat.r.drdy=0;    // not ready for a new command, //		switch(code)	{		case 0x90:   //EDD  	        dide_stat.r.bsy=1;		dide_err.r.icrc=0;		dide_dev.r.dev=0; 		dide_sectorcount.data=0x01;  		dide_lbam.data=00; 		dide_lbal.data=00;		dide_lbah.data=00;		dide_dev.data=00;		dide_astat.data|=0x0d;   		dide_stat.r.bsy=0; 		break;	case 0xec:  //Identify Device, not much thing to do here		dide_stat.r.bsy=1;		words_counter=0;		dide_stat.r.drq=1;		dide_stat.r.bsy=0;		break;	case 0xef: //set features 		dide_stat.r.bsy=1;  		dide_stat.r.drdy=1;		features.com[features.c++]=dide_feature.data;		features.subcom[features.c++]=dide_sectorcount.data;		dide_stat.r.bsy=0;		dide_stat.r.drq=0;		break;	case 0xc8: //read DMA	case 0xca:  //write DMA		if (dide_err.r.abrt){			if(dide_devcon.r.nien==0 && bmide_stat.r.interrupt==1)				dide_stat.r.bsy=dide_stat.r.drq=0;			else{				dide_stat.r.bsy=dide_stat.r.drq=0;				dide_stat.r.drdy=1;			}		}		else {			dide_stat.r.bsy = 1;			dide_stat.r.drq = 0; 			dide_devcon.r.nien=1;			dma_transfer();			dide_stat.r.bsy=0;			dide_stat.r.drq=1; 			dide_devcon.r.nien=0;          		};		break;	default:		log("IDE device: Write unimplemented command %d", code); 		break;	//DRDY=1, device is ready to receive commands //	dide_comm.data=0x40;  	}	set_interrupt();	}void IDE::set_interrupt()             {  	if(dide_devcon.r.nien==0)	{	dide_devcon.r.nien=1;  		bmide_stat.r.interrupt=1; 		intctrl->deliver_interrupt(irq);   	}}void IDE::clear_interrupt(){		intctrl->clear_interrupt(irq);	dide_devcon.r.nien=0;}void IDE::dma_transfer(){	UInt64 temp, taddr, maddr, foffset, dma_data; 	UInt64 mbytes=0, sbytes, sector_count, i;	UInt32 fdata;	int eot =0;	bmide_stat.r.active=1;  	bmide_stat.r.interrupt=0;	//read the DMA PDR mem adress form the table	taddr = bmide_dtpr.data;	if (dide_sectorcount.data==0)		sector_count = 256;	else		sector_count = dide_sectorcount.data; 	sbytes = sector_count * 512;	//get sector base address from LBA registers and the offset which sector is mapped to//	temp=(dide_lbah.data<<16) | (dide_lbam.data<<8) | (dide_lbal.data);	foffset = temp*512;	FILE* fp; 	if ((fp= fopen(conf.file_name, "rb+")) == NULL)	{		printf("can not open file\n");		exit(0);	};	fseek(fp, foffset, 0);	while (eot!=1)	{		bus->read(taddr, &temp, 4);		maddr=idedma_descriptor.r.mem_paddr=temp;		taddr = taddr + 4;		bus->read(taddr, &temp, 4);		mbytes = idedma_descriptor.r.mbyte_count= temp & 0x0000ffff;		taddr = taddr + 4;		eot = idedma_descriptor.r.eot= (temp & 0x80000000) >> 31; 		if (!bmide_comm.r.read_write) {			for (i=0; i< (mbytes/4); i++) {					bus->read(maddr, &temp, 4);				fdata = temp;               				fwrite(&fdata, sizeof(fdata), 1, fp);				maddr = maddr + 4;			};				}                else {			for (i=0; i<(mbytes/8); i++) {					fread(&fdata, sizeof(fdata), 1, fp);				dma_data = (UInt64)fdata;				fread(&fdata, sizeof(fdata), 1, fp);				dma_data = (dma_data << 32) | (UInt64)fdata;  				bus->write(maddr, &dma_data, 8);				maddr = maddr + 8;			};									};		        };	if (fclose(fp)!=0)		printf("errors in closing file!\n" );	if (sbytes | mbytes==0) {		bmide_stat.r.active=0;		bmide_stat.r.interrupt=1;   	};	if (sbytes==0 && mbytes!=0) {		bmide_stat.r.active=1;		bmide_stat.r.interrupt=1;   	};	if (sbytes!=0 && mbytes==0) {		bmide_stat.r.error=1;		bmide_stat.r.active=0;		bmide_stat.r.interrupt=0;		dide_err.r.abrt=1;  	};}

⌨️ 快捷键说明

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