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

📄 dev_net_s3c4510b.c

📁 skyeye-1.2-RC7-3的源代码
💻 C
字号:
//zzc: 2005-2-6 currently not support network simulation on Cygwin#ifndef __CYGWIN__/*	dev_net_s3c4510b.c - skyeye S3C4510B ethernet controllor simulation	Copyright (C) 2003 - 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  *//* * 06/17/2005   initial verion for s3c4510b *                      walimis <wlm@student.dlut.edu.cn> */#include <signal.h>#include <sys/time.h>//koodailar add for mingw 2005.12.18 ----------------------------------------#ifdef __MINGW32__#include "arch/arm/common/armdefs.h"#include "device/skyeye_device.h"#else#include "armdefs.h"#include "skyeye_device.h"#endif// end ----------------------------------------------------------------------#include "dev_net_s3c4510b.h"static struct device_default_value s3c4510b_net_def[] = {	/* name         base        size   interrupt array */	{"s3c4510b", 0x3FF9000, 0x2000, {16, 17, 18, 19}},	{NULL},};#define MAX_DEVICE_NUM 10static struct device_desc *s3c4510b_devs[MAX_DEVICE_NUM];#if 0voidnet_s3c4510b_set_update_intr (struct device_desc *dev){	struct device_interrupt *intr = &dev->intr;	struct machine_config *mc = (struct machine_config *) dev->mach;	struct net_s3c4510b_io *io = (struct net_s3c4510b_io *) dev->data;	mc->mach_set_intr (intr->interrupts[INT_S3C4510B]);	mc->mach_update_intr (mc);}inline voidset_time (int packets){	struct itimerval value;	value.it_value.tv_sec = 0;	value.it_value.tv_usec = packets;	value.it_interval = value.it_value;	setitimer (ITIMER_REAL, &value, NULL);}static voidsend_interrupt (){	int i;	struct device_desc *dev;	for (i = 0; i < MAX_DEVICE_NUM; i++) {		if ((dev = s3c4510b_devs[i]) != NULL) {			struct net_device *net_dev =				(struct net_device *) dev->dev;			struct machine_config *mc =				(struct machine_config *) dev->mach;			struct net_s3c4510b_io *io =				(struct net_s3c4510b_io *) dev->data;			if ((io->need_update)) {				/* only update once. */				net_s3c4510b_set_update_intr (dev);				io->need_update = 0;				set_time (0);				return;			}		}	}}static voidinit_sigaction (void){	struct sigaction act;	act.sa_handler = send_interrupt;	act.sa_flags = 0;	sigemptyset (&act.sa_mask);	sigaction (SIGALRM, &act, NULL);}#endifstatic voidmac_write (struct device_desc *dev){	struct device_interrupt *intr = &dev->intr;	struct net_device *net_dev = (struct net_device *) dev->dev;	struct net_s3c4510b_io *io = (struct net_s3c4510b_io *) dev->data;	struct machine_config *mc = (struct machine_config *) dev->mach;	ARMul_State *state = (ARMul_State *) mc->state;	fault_t fault;	u32 ptr, status, len;	int i;	fault = mmu_read_word (state, io->bdmatxptr, &ptr);	/*	   if( fault ) {	   *addr = io->bdmatxptr;	   return fault;	   }	 */	if (!(ptr & BDMA_owner))		return 0;	ptr &= ~BDMA_owner;	fault = mmu_read_word (state, io->bdmatxptr + 8, &len);	/*	   if( fault ) {	   *addr = io->bdmatxptr + 8;	   return fault; 	   }       	 */	len &= 0xffff;	if (len > sizeof (io->mac_buf))		return;	for (i = 0; i < len; i++) {		fault = mmu_read_byte (state, ptr + i, io->mac_buf + i);		/*		   if( fault ) {		   *addr = ptr + i;		   return fault;		   }		 */	}	//Update TXstatus 	status = len | (Comp << 16);	fault = mmu_write_word (state, io->bdmatxptr + 8, status);	//print_packet(io->mac_buf, len);	/*	   if( fault ) {	   *addr = io->bdmatxptr + 8;	   return fault;	   }	 */	//set owner bit of desc to CPU	fault = mmu_write_word (state, io->bdmatxptr, ptr);	/*	   if( fault ) {	   *addr = io->bdmatxptr;	   return fault;	   }	 */	//get next desc	fault = mmu_read_word (state, io->bdmatxptr + 12, &io->bdmatxptr);	/*	   if( fault ) {	   *addr = io->bdmatxptr + 12;	 */	net_dev->net_write (net_dev, io->mac_buf, len);	//write( skyeye_config.net[0].fd, io->mac_buf, len  );	//trigger interrupt	if (io->mactxcon & EnComp) {		mc->mach_set_intr (intr->interrupts[INT_S3C4510B_MACTX]);		mc->mach_update_intr (mc);		//s3c4510b_set_interrupt(INT_MACTX);		//s3c4510b_update_int(state);	}	return 0;}static voidmac_read (struct device_desc *dev){	struct device_interrupt *intr = &dev->intr;	struct net_device *net_dev = (struct net_device *) dev->dev;	struct net_s3c4510b_io *io = (struct net_s3c4510b_io *) dev->data;	struct machine_config *mc = (struct machine_config *) dev->mach;	ARMul_State *state = (ARMul_State *) mc->state;	int packet_len, s3c4510b_len;	fault_t fault;	u32 ptr, status_len;	int n, i;	//*addr = 0;	packet_len =		net_dev->net_read (net_dev, io->mac_buf,				   sizeof (io->mac_buf));	//n = read(skyeye_config.net[0].fd, mac_buf, sizeof(mac_buf));	if (packet_len <= 0)		return 0;	fault = mmu_read_word (state, io->bdmarxptr, &ptr);	//print_packet(io->mac_buf, packet_len);	/*	   if( fault ) {	   *addr = io->bdmarxptr;	   return fault;	   }	 */	if (!(ptr & BDMA_owner))		return 0;	ptr &= ~BDMA_owner;	//if( len + 2  > sizeof(mac_buf) ) return 0;	/* FIXME:for s3c4510b frame, ptr offset is 2 */	for (i = 0; i < packet_len; i++) {		fault = mmu_write_byte (state, ptr + 2 + i,					*(io->mac_buf + i));		/*		   if(fault) {		   *addr = ptr + 2 + i;		   return fault;		   }		 */	}	//in desc, set Good bit for RX status , and set len 	status_len = (Good << 16) | (packet_len + 4);	//printf("status_len:%x\n",status_len); 	fault = mmu_write_word (state, io->bdmarxptr + 8, status_len);	/*	   if(fault) {	   *addr = io->bdmarxptr+8;	   return fault;	   }	 */	//set owner bit of desc to CPU	fault = mmu_write_word (state, io->bdmarxptr, ptr);	/*	   if(fault) {	   *addr = io->bdmarxptr;	   return fault;	   }	 */	//get next desc	fault = mmu_read_word (state, io->bdmarxptr + 12, &io->bdmarxptr);	/*	   if(fault) {	   *addr = io->bdmarxptr + 12;	   return fault;	   }	 */	/* update bdmastat register */	io->bdmastat |= S_BRxRDF;	mc->mach_set_intr (intr->interrupts[INT_S3C4510B_BDMARX]);	mc->mach_update_intr (mc);	return 0;}static voidnet_s3c4510b_fini (struct device_desc *dev){	struct net_s3c4510b_io *io = (struct net_s3c4510b_io *) dev->data;	free (dev->dev);	free (io);}static voidnet_s3c4510b_reset (struct device_desc *dev){	struct net_device *net_dev = (struct net_device *) dev->dev;	struct net_s3c4510b_io *io = (struct net_s3c4510b_io *) dev->data;	int i;	io->bdmatxptr = 0xFFFFFFFF;	io->bdmarxptr = 0xFFFFFFFF;}static voidnet_s3c4510b_update (struct device_desc *dev){	struct device_interrupt *intr = &dev->intr;	struct net_device *net_dev = (struct net_device *) dev->dev;	struct net_s3c4510b_io *io = (struct net_s3c4510b_io *) dev->data;	struct machine_config *mc = (struct machine_config *) dev->mach;	if ((io->bdmarxcon & RxEn)) {//koodailar modify it for mingw 2005.12.18--------------------------------------#ifdef __MINGW32__		//whenever possible, update it		mac_read (dev);#else                          		fd_set frds;		struct timeval tv;		int ret;		FD_ZERO (&frds);		FD_SET (net_dev->net_fd, &frds);		tv.tv_sec = 0;		tv.tv_usec = 0;		if ((ret =		     select (net_dev->net_fd + 1, &frds, NULL, NULL,			     &tv)) > 0) {			if (FD_ISSET (net_dev->net_fd, &frds)) {				mac_read (dev);			}		}#endif//end koodailar ----------------------------------------------------------------			}}intnet_s3c4510b_read_word (struct device_desc *dev, u32 addr, u32 * data){	struct net_device *net_dev = (struct net_device *) dev->dev;	struct net_s3c4510b_io *io = (struct net_s3c4510b_io *) dev->data;	int offset = (u16) (addr - dev->base + 0x9000);	int ret = ADDR_HIT;	//printf("%s:addr %x, %x\n", __FUNCTION__, addr, MACON);	*data = 0;	switch (offset) {	case MACON:		*data = io->macon;		break;	case CAMCON:		*data = io->camcon;		break;	case MACTXCON:		*data = io->mactxcon;		break;	case MACTXSTAT:		*data = io->mactxstat;		break;	case MACRXCON:		*data = io->macrxcon;		break;	case MACRXSTAT:		*data = io->macrxstat;		break;	case STADATA:		*data = io->stadata;		break;	case STACON:		*data = io->stacon;		break;	case CAMEN:		*data = io->camen;		break;	case BDMATXPTR:		*data = io->bdmatxptr;		break;	case BDMARXPTR:		*data = io->bdmarxptr;		break;	case BDMASTAT:		*data = io->bdmastat;		break;	case BDMARXCON:		*data = io->bdmarxcon;		break;	case BDMATXCON:		*data = io->bdmatxcon;		break;	case BDMARXLSZ:		*data = io->bdmarxlsz;		break;	default:		break;	}	return ret;}intnet_s3c4510b_write_word (struct device_desc *dev, u32 addr, u32 data){	struct net_device *net_dev = (struct net_device *) dev->dev;	struct net_s3c4510b_io *io = (struct net_s3c4510b_io *) dev->data;	int offset = (u16) (addr - dev->base + 0x9000);	int ret = ADDR_HIT;	//printf("%s\n", __FUNCTION__);	switch (offset) {	case MACTXCON:		if (data & TxEn == TxEn) {			/*			   u32 addr;			   fault_t fault;			   fault = mac_write(dev);			   if( fault ) {			   mmu_data_abort(state, fault, addr);			   return;			   }			 */			mac_write (dev);		}		io->mactxcon = data;		break;	case BDMATXPTR:		io->bdmatxptr = data;		break;	case BDMARXPTR:		io->bdmarxptr = data;		break;	case BDMASTAT:		io->bdmastat &= (~data);		break;	case MACON:		io->macon = data;		break;	case MACRXCON:		io->macrxcon = data;		break;	case BDMARXCON:		io->bdmarxcon = data;		break;	case BDMATXCON:		io->bdmatxcon = data;		break;	case BDMARXLSZ:		io->bdmarxlsz = data;		break;	case CAMEN:		io->camen = data;		break;	default:		break;	}	return ret;}static intnet_s3c4510b_setup (struct device_desc *dev){	int i;	int enough = 0;	struct net_s3c4510b_io *io;	struct device_interrupt *intr = &dev->intr;	dev->fini = net_s3c4510b_fini;	dev->reset = net_s3c4510b_reset;	dev->update = net_s3c4510b_update;	dev->read_word = net_s3c4510b_read_word;	dev->write_word = net_s3c4510b_write_word;	io = (struct net_s3c4510b_io *)		malloc (sizeof (struct net_s3c4510b_io));	memset (io, 0, sizeof (struct net_s3c4510b_io));	if (io == NULL)		return 1;	dev->data = (void *) io;	net_s3c4510b_reset (dev);	//init_sigaction();	/* see if we need to set default values.	 * */	set_device_default (dev, s3c4510b_net_def);	for (i = 0; i < MAX_DEVICE_NUM; i++) {		if (s3c4510b_devs[i] == NULL) {			s3c4510b_devs[i] = dev;			enough = 1;			break;		}	}	if (enough == 0)		return 1;	return 0;}voidnet_s3c4510b_init (struct device_module_set *mod_set){	int i;	register_device_module ("s3c4510b", mod_set, &net_s3c4510b_setup);	for (i = 0; i < MAX_DEVICE_NUM; i++)		s3c4510b_devs[i] = NULL;}//zzc:#endif __CYGWIN__#endif

⌨️ 快捷键说明

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