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

📄 skyeye_mach_lpc2210.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	skyeye_mach_lpc2210.c - define machine lpc2210 for skyeye	Copyright (C) 2003 Skyeye Develop Group	for help please send mail to <skyeye-developer@lists.gro.clinux.org>		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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  *//* * 10/02/2007 	Add support for RTEMS/lpc2210 bsp. Be care that the clock in  *              skyeye lpc2210 support is 1000 times faster than the real hardware *              clock *		rayx <rayx.cn@gmail.com>  * 3/24/2003 	init this file. * 		add machine lpc's function.Most taken from original armio.c  * 		include: lpc_mach_init, lpc_io_do_cycle * 		lpc_io_read_word, lpc_io_write_word *		walimis <walimi@peoplemail.com.cn>  *		 *3/24/2003	chenyu <chenyu-tmlinux@hpclab.cs.tsinghua.edu.cn> has done the *		necessary work to armio.c * */#include "armdefs.h"#include "lpc.h"//#include "skyeye-ne2k.h"/* 2007-01-18 added by Anthony Lee : for new uart device frame */#include "skyeye_uart.h"#define TC_DIVISOR	(50)	/* Set your BogoMips here :) may move elsewhere*/#define DEBUG 0#if DEBUG#define DBG_PRINT(a...) fprintf(stderr,##a)#else#define DBG_PRINT(a...)#endiftypedef struct timer{	ARMword	ir;	ARMword tcr;	ARMword tc;	ARMword pr;	ARMword pc;	ARMword mcr;	ARMword mr0;	ARMword mr1;	ARMword mr2;	ARMword mr3;	ARMword ccr;	ARMword cr0;	ARMword cr1;	ARMword cr2;	ARMword cr3;	ARMword emr;} lpc2210_timer_t;typedef struct uart{	ARMword	rbr;	ARMword thr;	ARMword ier;	ARMword iir;	ARMword fcr;	ARMword lcr;	ARMword lsr;	ARMword msr;	ARMword scr;	ARMword dll;	ARMword dlm;	char t_fifo[16];	char r_fifo[16];} lpc2210_uart_t;typedef struct pll{	ARMword	con;	ARMword cfg;	ARMword stat;	ARMword feed;} lpc2210_pll_t;typedef struct vic{	ARMword IRQStatus;	ARMword FIQStatus;	ARMword RawIntr;	ARMword IntSelect;	ARMword IntEnable;	ARMword IntEnClr;	ARMword SoftInt;	ARMword SoftIntClear;	ARMword Protection;	ARMword Vect_Addr;	ARMword DefVectAddr;	ARMword VectAddr[15];	ARMword VectCntl[15];} lpc2210_vic_t;typedef struct lpc2210_io {        ARMword         syscon;                 /* System control */        ARMword         sysflg;                 /* System status flags */	lpc2210_pll_t		pll;	lpc2210_timer_t	timer[2];	lpc2210_vic_t		vic;	ARMword			pinsel0;	/*Pin Select Register*/	ARMword			pinsel1;	ARMword			pinsel2;			ARMword			bcfg[4];	/*BCFG Extend Mem control*/	ARMword			vpbdiv;		/*VPB Divider control*/        int             	tc_prescale;	lpc2210_uart_t	uart[2];                 /* Receive data register */	ARMword		mmcr;			/*Memory mapping control register*/	ARMword		vibdiv;		/*real time regs*/	ARMword		sec;	ARMword		min;	ARMword		hour;	ARMword		dom;	ARMword		dow;	ARMword		doy;	ARMword		month;	ARMword		year;	ARMword		preint;	ARMword		prefrac;	ARMword		ccr;		/*mam accelerator module*/	ARMword		mamcr;	ARMword		mamtim;	} lpc2210_io_t;static lpc2210_io_t lpc2210_io;#define io lpc2210_iovoid lpc2210_io_write_word(ARMul_State *state, ARMword addr, ARMword data);static void lpc2210_update_int(ARMul_State *state){	u32 irq = 0;	int i;	//state->NfiqSig = (~(io.vic.RawIntr&io.vic.IntEnable& io.vic.)) ? LOW : HIGH;	irq = io.vic.RawIntr & io.vic.IntEnable ;	//add by linxz	//printf("SKYEYE:RawIntr:0x%x,IntEnable:0x%x\n", io.vic.RawIntr, io.vic.IntEnable);	io.vic.IRQStatus = irq & ~io.vic.IntSelect;	io.vic.FIQStatus = irq & io.vic.IntSelect;		//here only deals some important int:	//uart0 and timer0, other peripheral's int reqs are ignored.	//added and rmked by linxz		//UART0, Int src: 6	if(io.vic.IRQStatus &IRQ_UART0){		for ( i = 0; i<=15; i++ )		{			if ( ((io.vic.VectCntl[i] & 0xf) == 6 ) && (io.vic.VectCntl[i] & 0x20) )				break;		}		if ( ((io.vic.VectCntl[i] & 0xf) == 6 ) && (io.vic.VectCntl[i] & 0x20) )			io.vic.Vect_Addr = io.vic.VectAddr[i];					}		//TIMER0, Int src: 4	if(io.vic.IRQStatus &IRQ_TC0){		for ( i = 0; i<=15; i++ )		{			if ( ((io.vic.VectCntl[i] & 0xf) == 4 ) && (io.vic.VectCntl[i] & 0x20) )				break;		}		if ( ((io.vic.VectCntl[i] & 0xf) == 4 ) && (io.vic.VectCntl[i] & 0x20) )		{			io.vic.Vect_Addr = io.vic.VectAddr[i];							//printf("VicVect load vectaddr%d:%08x", i, io.vic.Vect_Addr);		}	}		state->NirqSig = io.vic.IRQStatus ? LOW:HIGH; 	state->NfiqSig = io.vic.FIQStatus ? LOW:HIGH;}static void lpc2210_io_reset(ARMul_State *state){	//io.timer[0].pr = 500000;/*prescale value*/	//rmked by linxz	io.timer[0].pr = 0;	io.pll.stat |= 1<<10;   /*PLL state register should be 1<<10 when hardware ready*/		io.vic.IRQStatus = 0;	io.vic.FIQStatus = 0;	io.vic.RawIntr = 0;	//added by linxz	io.vic.IntSelect = 0;		io.uart[0].lsr |= 0x60;	io.uart[0].iir = 0x01;	io.pinsel0 = 0;	io.pinsel1 = 0x15400000;	//io.pinsel2 = 		FIX ME		io.bcfg[0] = 0x0000fbef;	io.bcfg[1] = 0x2000fbef;	io.bcfg[2] = 0x1000fbef;	io.bcfg[3] = 0x0000fbef;		io.vibdiv  = 0;}/*lpc2210 io_do_cycle*/void lpc2210_io_do_cycle(ARMul_State *state){	int t;	io.timer[0].pc++;	io.timer[1].pc++;	//add by linxz	//printf("SKYEYE:Timer0 PC:%d, TC:%d\n", io.timer[0].pc, io.timer[0].tc);	//printf(",MR0:%d,PR:%d,RISR:%d,IER:%d,ISLR:%d,ISR:%d\n", io.timer[0].mr0, io.timer[0].pr, io.vic.RawIntr, io.vic.IntEnable, io.vic.IntSelect, io.vic.IRQStatus);	if (!(io.vic.RawIntr & IRQ_TC0)) {	//no timer0 int yet		if (io.timer[0].pc >= io.timer[0].pr+1) {					io.timer[0].tc++;			io.timer[0].pc = 0;		       	if(io.timer[0].tc >= io.timer[0].mr0/1000) /*Skyeye's clock is far more slow than the real Ocs. I have to make the clock interrupt come quicker*/{	//		if(io.timer[0].tc == 20){		       		io.vic.RawIntr |= IRQ_TC0;					io.timer[0].tc = 0;				//add by linxz				//printf("\r\nI\r\n");				}			lpc2210_update_int(state);		}	}	if(io.timer[0].pc == 0){		if (!(io.vic.RawIntr & IRQ_UART0)) {		/* 2007-01-18 modified by Anthony Lee : for new uart device frame */		struct timeval tv;		unsigned char buf;		tv.tv_sec = 0;		tv.tv_usec = 0;		if(skyeye_uart_read(-1, &buf, 1, &tv, NULL) > 0)		{			//printf("SKYEYE:get input is %c\n",buf);			io.uart[0].rbr = buf;			io.uart[0].lsr |= 0x1;			io.vic.RawIntr |= IRQ_UART0;			lpc2210_update_int(state);		}        }/* if (rcr > 0 && ...*/	}}ARMword	lpc2210_fix_int(ARMword val){/*	ARMword ret = 0;	if (val & (1 << 2))		ret |= URXINT;	if (val & (1 << 5))		ret |= TC1OI;	if (val & (1 << 6))		ret |= TC2OI;	if (val & (1 << 16))		ret |= AT91_EXT0;*/	return(val);}ARMword	lpc2210_unfix_int(ARMword val){/*	ARMword ret = 0;	if (val & URXINT)		ret |= (1 << 2);	if (val & TC1OI)		ret |= (1 << 5);	if (val & TC2OI)		ret |= (1 << 6);	if (val & AT91_EXT0)		ret |= (1 << 16);		*/	return(val);}ARMwordlpc2210_uart_read(ARMul_State *state, ARMword addr,int i){	ARMword data;	//printf("lpc2210_uart_read,addr=%x\n",addr);	switch ((addr & 0xfff) >> 2) {	case 0x0: // RbR		io.uart[i].lsr &= ~0x1;		if(i==0)			io.vic.RawIntr &= ~IRQ_UART0;		else			io.vic.RawIntr &= ~IRQ_UART1;		lpc2210_update_int(state);		data = io.uart[i].rbr;		break;		case 0x1: // ier		data = io.uart[i].ier;		break;	case 0x2: // iir		data = io.uart[i].iir;		break;	case 0x3: // IDR	case 0x4: // IMR	case 0x5: // LSR		data = io.uart[i].lsr;		break;	case 0x6: // MSR		    data = io.uart[i].msr;				    break;							case 0x7: // SCR				data = io.uart[i].scr;						break;																	default:		DBG_PRINT("uart_read(%s=0x%08x)\n", "uart_reg", addr);				break;	}	return(data);}voidlpc2210_uart_write(ARMul_State *state, ARMword addr, ARMword data,int i){	static ARMword tx_buf = 0;	//DBG_PRINT("uart_write(0x%x, 0x%x)\n", (addr & 0xfff) >> 2, data);	switch ((addr & 0xfff) >> 2) {		case 0x0: // THR		{			char c = data;			/* 2007-01-18 modified by Anthony Lee : for new uart device frame */			skyeye_uart_write(-1, &c, 1, NULL);			//io.uart[0].lsr |= 0x40;			io.uart[0].lsr |= 0x20;					}		case 0x2: //FCR		{			io.uart[i].fcr = data;			break;		}		case 0x7: // SCR		        io.uart[i].scr = data;						break;		default:													//printf("%c", data); fflush(stdout);			DBG_PRINT("uart_write(%s=0x%08x)\n", "uart_reg", addr);									break;	}}ARMword lpc2210_io_read_word(ARMul_State *state, ARMword addr){	/* * 	 * The lpc2210 system registers * 	 	 */	ARMword data = -1;	static ARMword current_ivr = 0; /* mega hack,  2.0 needs this */	int i;	ARMword dataimr = 0;	switch (addr) {	case 0xfffff000: /* ISR *///		data = unfix_int(io.intsr);//		dataimr = unfix_int(io.intmr);		data = io.vic.IRQStatus;		DBG_PRINT("read ISR=%d\n", data);		break;	case 0xfffff004: /* interrupt status register */		data = io.vic.FIQStatus;		DBG_PRINT("SKYEYE:read ISR=%x,%x\n", data, io.vic.FIQStatus);		break;	case 0xfffff008: /* IMR */		data = io.vic.RawIntr;		break;	case 0xfffff00c: /* CORE interrupt status register */		data = io.vic.IntSelect;		break;	case 0xfffff010: /* IER */		data = io.vic.IntEnable;		DBG_PRINT("read IER=%x,after update IntEnable=%x\n", data,io.vic.IntEnable);		break;	case 0xfffff014: /* Int Enable Clr Reg */		data = io.vic.IntEnClr;				lpc2210_update_int(state);		break;		case 0xfffff034: /* Default Vector Addr Reg */		data = io.vic.DefVectAddr ;		break;	case 0xfffff030: /* VAR */		data = io.vic.Vect_Addr ;		break;	case 0xfffff100: /* VicVectAddr0*/		data = io.vic.VectAddr[0] ;		break;	case 0xfffff200: /*VicVectCntl0*/		data = io.vic.VectCntl[0];		break;					/*Timer0 */

⌨️ 快捷键说明

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