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

📄 skyeye_mach_s3c2440.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
字号:
/*	skyeye_mach_s3c2440.c - define machine S3C2440 for skyeye	Copyright (C) 2005 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 */#include "armdefs.h"#include "s3c2440.h"//zzc:2005-1-1#ifdef __CYGWIN__//chy 2005-07-28#include <time.h>//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------/*struct timeval{  int tv_sec;  int tv_usec;};*///AJ2D--------------------------------------------------------------------------#endif/* 2007-01-18 added by Anthony Lee : for new uart device frame */#include "skyeye_uart.h"#define TC_DIVISOR	(1)	/* Set your BogoMips here :) may move elsewhere */typedef struct s3c2440_io{	u32 srcpnd;		/* Indicate the interrupt request status */	u32 intmod;		/* Interrupt mode register */	u32 intmsk;		/* Determine which interrupt source is masked */	u32 priority;		/* IRQ priority control register */	u32 intpnd;		/* Indicate the interrupt request status */	u32 intoffset;		/* Indicate the IRQ interrupt request source */	u32 subsrcpnd;		/* Indicate the interrupt request status */	u32 intsubmsk;		/* Determin which interrupt source is masked */	struct s3c2440_timer_io timer;	/* Timer */	struct s3c2440_uart_io uart0;	/* uart0 */	struct s3c2440_clkpower clkpower;	/* clock and power management */	int tc_prescale;} s3c2440_io_t;static s3c2440_io_t s3c2440_io;#define io s3c2440_iostatic inline voids3c2440_set_subsrcint (unsigned int irq){	io.subsrcpnd |= irq;}static inline voids3c2440_update_subsrcint (){	u32 requests;	s3c2440_set_subsrcint (UART_INT_TXD << (0 * 3));	s3c2440_set_subsrcint (UART_INT_TXD << (1 * 3));	s3c2440_set_subsrcint (UART_INT_TXD << (2 * 3));	requests = ((io.subsrcpnd & (~io.intsubmsk)) & 0x7fff);	if (requests & 0x7)		io.srcpnd |= INT_UART0;	if (requests & 0x38)		io.srcpnd |= INT_UART1;	if (requests & 0x1c0)		io.srcpnd |= INT_UART2;	if (requests & 0x600)		io.srcpnd |= INT_ADC;}static voids3c2440_update_int (ARMul_State * state){	ARMword requests;	s3c2440_update_subsrcint ();	requests = io.srcpnd & (~io.intmsk & INT_MASK_INIT);	state->NfiqSig = (requests & io.intmod) ? LOW : HIGH;	state->NirqSig = (requests & ~io.intmod) ? LOW : HIGH;}static voids3c2440_io_reset (ARMul_State * state){	memset (&s3c2440_io, 0, sizeof (s3c2440_io));	io.tc_prescale = TC_DIVISOR;	io.uart0.ulcon = UART_ULCON_INIT;	io.uart0.utrstat = UART_UTRSTAT_INIT;	//io.timer.tcnt[4] = 25350;	io.clkpower.locktime = 0x00FFFFFF;	io.clkpower.mpllcon = 0x0005C080;	io.clkpower.upllcon = 0x00028080;	io.clkpower.clkcon = 0x7FFF0;	io.clkpower.clkslow = 0x4;	io.intmsk = INT_MASK_INIT;	io.intpnd = 0x0;}/* s3c2440 io_do_cycle */static voids3c2440_io_do_cycle (ARMul_State * state){		io.tc_prescale--;	if (io.tc_prescale < 0) {		io.tc_prescale = TC_DIVISOR;		if ((io.timer.tcon & 0x100000) != 0) {			io.timer.tcnt[4]--;			if (io.timer.tcnt[4] < 0) {				io.timer.tcnt[4] = io.timer.tcntb[4];				/*timer 4 hasn't tcmp */				//io.timer.tcmp[4] = io.timer.tcmpb[4];				io.timer.tcnto[4] = io.timer.tcntb[4];				io.srcpnd |= INT_TIMER4;				s3c2440_update_int (state);				return;			}		}		if (((io.uart0.utrstat & 0x1) == 0x0)		    && ((io.uart0.ucon & 0x3) == 0x1)) {			/* 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)			{				io.uart0.urxh = (int) buf;				/* Receiver Ready				 * */				io.uart0.utrstat |= (0x1);				/* pending usart0 interrupt				 * */				s3c2440_set_subsrcint (UART_INT_RXD <<						       (0 * 3));				//io.srcpnd |= INT_UART0;				s3c2440_update_int (state);				return;			}		}		//s3c2440_update_int (state);	}			/* if (io.tc_prescale < 0) */}static voids3c2440_uart_read (u32 offset, u32 * data){	switch (offset) {	case ULCON:		*data = io.uart0.ulcon;		break;	case UCON:		*data = io.uart0.ucon;		break;	case UFCON:		*data = io.uart0.ufcon;		break;	case UMCON:		*data = io.uart0.umcon;		break;	case UTRSTAT:		*data = io.uart0.utrstat;		break;	case UERSTAT:		*data = io.uart0.uerstat;		break;	case UFSTAT:		*data = io.uart0.ufstat;		break;	case UMSTAT:		*data = io.uart0.umstat;		break;	case URXH:		/* receive char		 * */		*data = io.uart0.urxh;		io.uart0.utrstat &= (~0x1);	/* clear strstat register bit[0] */		break;	case UBRDIV:		*data = io.uart0.ubrdiv;		break;	default:		break;	}	SKYEYE_DBG ("%s(0x%x, 0x%x)\n", __func__, offset, data);}static voids3c2440_uart_write (ARMul_State * state, u32 offset, u32 data){	SKYEYE_DBG ("s3c2440_uart_write(0x%x, 0x%x)\n", offset, data);	switch (offset) {	case ULCON:		io.uart0.ulcon = data;		break;	case UCON:		io.uart0.ucon = data;		break;	case UFCON:		io.uart0.ufcon = data;		break;	case UMCON:		io.uart0.umcon = data;		break;	case UTRSTAT:		io.uart0.utrstat = data;		break;	case UERSTAT:		io.uart0.uerstat = data;		break;	case UFSTAT:		io.uart0.ufstat = data;		break;	case UMSTAT:		io.uart0.umstat = data;		break;	case UTXH:		{			char c = data;			/* 2007-01-18 modified by Anthony Lee : for new uart device frame */			skyeye_uart_write(-1, &c, 1, NULL);			io.uart0.utrstat |= 0x6;	//set strstat register bit[0]			if ((io.uart0.ucon & 0xc) == 0x4) {				s3c2440_set_subsrcint (UART_INT_TXD <<						       (0 * 3));				s3c2440_update_int (state);			}		}		break;	case UBRDIV:		io.uart0.ubrdiv = data;		break;	default:		break;	}	SKYEYE_DBG ("%s(0x%x, 0x%x)\n", __func__, offset, data);}static voids3c2440_timer_read (u32 offset, u32 * data){	switch (offset) {	case TCFG0:		*data = io.timer.tcfg0;		break;	case TCFG1:		*data = io.timer.tcfg1;		break;	case TCON:		*data = io.timer.tcon;		break;	case TCNTB0:	case TCNTB1:	case TCNTB2:	case TCNTB3:	case TCNTB4:		{			int n = (offset - 0xC) / 0xC;			*data = io.timer.tcntb[n];		}		break;	case TCMPB0:	case TCMPB1:	case TCMPB2:	case TCMPB3:		{			int n = (offset - 0x10) / 0xC;			*data = io.timer.tcmpb[n];		}		break;	case TCNTO0:	case TCNTO1:	case TCNTO2:	case TCNTO3:		{			int n = (offset - 0x10) / 0xC;			*data = io.timer.tcnto[n];		}		break;	case TCNTO4:		*data = io.timer.tcnto[4];		break;	default:		break;	}}static voids3c2440_timer_write (ARMul_State * state, u32 offset, u32 data){	switch (offset) {	case TCFG0:		io.timer.tcfg0 = data;		break;	case TCFG1:		io.timer.tcfg1 = data;		break;	case TCON:		{			io.timer.tcon = data;			if (io.timer.tcon) {			}		}		break;	case TCNTB0:	case TCNTB1:	case TCNTB2:	case TCNTB3:	case TCNTB4:		{			int n = (offset - 0xC) / 0xC;			//io.timer.tcntb[n] = data;			io.timer.tcntb[n] = 25350;		}		break;	case TCMPB0:	case TCMPB1:	case TCMPB2:	case TCMPB3:		{			int n = (offset - 0x10) / 0xC;			io.timer.tcmpb[n] = data;		}		break;	default:		break;	}}static ARMwords3c2440_io_read_word (ARMul_State * state, ARMword addr){	ARMword data = -1;	int i;	/*uart0 */	if ((addr >= UART_CTL_BASE0)	    && (addr < (UART_CTL_BASE0 + UART_CTL_SIZE))) {		s3c2440_uart_read ((u32) (addr - UART_CTL_BASE0),				   (u32 *) & data);	}	if ((addr >= PWM_CTL_BASE) && (addr < (PWM_CTL_BASE + PWM_CTL_SIZE))) {		s3c2440_timer_read ((u32) (addr - PWM_CTL_BASE),				    (u32 *) & data);	}	switch (addr) {	case SRCPND:		data = io.srcpnd;		break;	case INTMOD:		data = io.intmod;		break;	case INTMSK:		data = io.intmsk;		break;	case PRIORITY:		data = io.priority;		break;	case INTPND:	case INTOFFSET:		{			/*find which interrupt is pending */			int i;			for (i = 0; i < 32; i++) {				if (io.srcpnd & (1 << i))					break;			}			if (i < 32) {				io.intoffset = i;				io.intpnd = (1 << i);				if (addr == INTPND)					data = (1 << i);				else					data = i;			}			else				data = 0;		}		io.intpnd = (1 << io.intoffset);		//printf ("io.intoffset:%x, io.intpnd:%x (0x%08x) = 0x%08x\n", io.intoffset, io.intpnd, addr, data);		break;	case SUBSRCPND:		data = io.subsrcpnd;		break;	case INTSUBMSK:		data = io.intsubmsk;		break;		/* GPIO Register */	case GSTATUS1:		data = 0x32410000;		break;		/* Clock and Power Management Registers */	case LOCKTIME:		data = io.clkpower.locktime;		break;	case MPLLCON:		data = io.clkpower.mpllcon;		break;	case UPLLCON:		data = io.clkpower.upllcon;		break;	case CLKCON:		data = io.clkpower.clkcon;		break;	case CLKSLOW:		data = io.clkpower.clkslow;		break;	case CLKDIVN:		data = io.clkpower.clkdivn;		break;	default:		break;	}	return data;}static ARMwords3c2440_io_read_byte (ARMul_State * state, ARMword addr){	s3c2440_io_read_word (state, addr);}static ARMwords3c2440_io_read_halfword (ARMul_State * state, ARMword addr){	s3c2440_io_read_word (state, addr);}static voids3c2440_io_write_word (ARMul_State * state, ARMword addr, ARMword data){	if ((addr >= UART_CTL_BASE0)	    && (addr < UART_CTL_BASE0 + UART_CTL_SIZE)) {		s3c2440_uart_write (state, addr - UART_CTL_BASE0, data);	}	if ((addr >= PWM_CTL_BASE) && (addr < (PWM_CTL_BASE + PWM_CTL_SIZE))) {		s3c2440_timer_write (state, addr - PWM_CTL_BASE, data);	}	switch (addr) {	case SRCPND:		io.srcpnd &= (~data & INT_MASK_INIT);		break;	case INTMOD:		io.intmod = data;		break;	case INTMSK:		io.intmsk = data;		s3c2440_update_int (state);		break;	case PRIORITY:		io.priority = data;		break;	case INTPND:		io.intpnd &= (~data & INT_MASK_INIT);		io.intoffset = 0;		//printf ("io.intoffset:%x, io.intpnd:%x (0x%08x) = 0x%08x, pc:%x\n", io.intoffset, io.intpnd, addr, data, state->pc);		break;		/*read only */		//case INTOFFSET:		//      break;	case SUBSRCPND:		io.subsrcpnd &= (~data & INT_SUBMSK_INIT);		break;	case INTSUBMSK:		io.intsubmsk = data;		break;	default:		SKYEYE_DBG ("io_write_word(0x%08x) = 0x%08x\n", addr, data);		break;	}}static voids3c2440_io_write_byte (ARMul_State * state, ARMword addr, ARMword data){	SKYEYE_DBG ("SKYEYE: s3c2440_io_write_byte error\n");	s3c2440_io_write_word (state, addr, data);}static voids3c2440_io_write_halfword (ARMul_State * state, ARMword addr, ARMword data){	SKYEYE_DBG ("SKYEYE: s3c2440_io_write_halfword error\n");	s3c2440_io_write_word (state, addr, data);}voids3c2440_mach_init (ARMul_State * state, machine_config_t * this_mach){	ARMul_SelectProcessor (state, ARM_v4_Prop);	/* ARM920T uses LOW */	state->lateabtSig = LOW;	state->Reg[1] = 241;	//ARCH_S3C2440	this_mach->mach_io_do_cycle = s3c2440_io_do_cycle;	this_mach->mach_io_reset = s3c2440_io_reset;	this_mach->mach_io_read_byte = s3c2440_io_read_byte;	this_mach->mach_io_write_byte = s3c2440_io_write_byte;	this_mach->mach_io_read_halfword = s3c2440_io_read_halfword;	this_mach->mach_io_write_halfword = s3c2440_io_write_halfword;	this_mach->mach_io_read_word = s3c2440_io_read_word;	this_mach->mach_io_write_word = s3c2440_io_write_word;	this_mach->mach_update_int = s3c2440_update_int;}

⌨️ 快捷键说明

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