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

📄 shub.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
字号:
/* $Id$ * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved. */#ident  "$Revision: 1.167 $"#include <linux/types.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <asm/smp.h>#include <asm/irq.h>#include <asm/hw_irq.h>#include <asm/sn/sgi.h>#include <asm/sn/iograph.h>#include <asm/sn/invent.h>#include <asm/sn/hcl.h>#include <asm/sn/labelcl.h>#include <asm/sn/io.h>#include <asm/sn/sn_private.h>#include <asm/sn/klconfig.h>#include <asm/sn/sn_cpuid.h>#include <asm/sn/pci/pciio.h>#include <asm/sn/pci/pcibr.h>#include <asm/sn/xtalk/xtalk.h>#include <asm/sn/pci/pcibr_private.h>#include <asm/sn/intr.h>#include <asm/sn/sn2/shub_mmr_t.h>#include <asm/sal.h>#include <asm/sn/sn_sal.h>#include <asm/sn/sndrv.h>/* * Shub WAR for Xbridge Little Endian problem: *	Xbridge has to run in BIG ENDIAN even with Shub. *//* * io_sh_swapper: Turn on Shub byte swapping. *	All data destined to and from Shub to XIO are byte-swapped. */voidio_sh_swapper(nasid_t nasid, int onoff){    ii_iwc_u_t      ii_iwc;    ii_iwc.ii_iwc_regval = REMOTE_HUB_L(nasid, IIO_IWC);    ii_iwc.ii_iwc_fld_s.i_dma_byte_swap = onoff;    REMOTE_HUB_S(nasid, IIO_IWC, ii_iwc.ii_iwc_regval);    ii_iwc.ii_iwc_regval = REMOTE_HUB_L(nasid, IIO_IWC);}/* * io_get_sh_swapper: Return current Swap mode. *	1 = Swap on, 0 = Swap off. */intio_get_sh_swapper(nasid_t nasid){    ii_iwc_u_t      ii_iwc;    ii_iwc.ii_iwc_regval = REMOTE_HUB_L(nasid, IIO_IWC);    return(ii_iwc.ii_iwc_fld_s.i_dma_byte_swap);}#define SHUB_NUM_ECF_REGISTERS 8static uint32_t	shub_perf_counts[SHUB_NUM_ECF_REGISTERS];static shubreg_t shub_perf_counts_regs[SHUB_NUM_ECF_REGISTERS] = {	SH_PERFORMANCE_COUNTER0,	SH_PERFORMANCE_COUNTER1,	SH_PERFORMANCE_COUNTER2,	SH_PERFORMANCE_COUNTER3,	SH_PERFORMANCE_COUNTER4,	SH_PERFORMANCE_COUNTER5,	SH_PERFORMANCE_COUNTER6,	SH_PERFORMANCE_COUNTER7};static inline voidshub_mmr_write(cnodeid_t cnode, shubreg_t reg, uint64_t val){	int		   nasid = cnodeid_to_nasid(cnode);	volatile uint64_t *addr = (uint64_t *)(GLOBAL_MMR_ADDR(nasid, reg));	*addr = val;	__ia64_mf_a();}static inline voidshub_mmr_write32(cnodeid_t cnode, shubreg_t reg, uint32_t val){	int		   nasid = cnodeid_to_nasid(cnode);	volatile uint32_t *addr = (uint32_t *)(GLOBAL_MMR_ADDR(nasid, reg));	*addr = val;	__ia64_mf_a();}static inline uint64_tshub_mmr_read(cnodeid_t cnode, shubreg_t reg){	int		  nasid = cnodeid_to_nasid(cnode);	volatile uint64_t val;	val = *(uint64_t *)(GLOBAL_MMR_ADDR(nasid, reg));	__ia64_mf_a();	return val;}static inline uint32_tshub_mmr_read32(cnodeid_t cnode, shubreg_t reg){	int		  nasid = cnodeid_to_nasid(cnode);	volatile uint32_t val;	val = *(uint32_t *)(GLOBAL_MMR_ADDR(nasid, reg));	__ia64_mf_a();	return val;}static intreset_shub_stats(cnodeid_t cnode){	int i;	for (i=0; i < SHUB_NUM_ECF_REGISTERS; i++) {		shub_perf_counts[i] = 0;		shub_mmr_write32(cnode, shub_perf_counts_regs[i], 0);	}	return 0;}static intconfigure_shub_stats(cnodeid_t cnode, unsigned long arg){	uint64_t	*p = (uint64_t *)arg;	uint64_t	i;	uint64_t	regcnt;	uint64_t	regval[2];	if (copy_from_user((void *)&regcnt, p, sizeof(regcnt)))	    return -EFAULT;	for (p++, i=0; i < regcnt; i++, p += 2) {		if (copy_from_user((void *)regval, (void *)p, sizeof(regval)))		    return -EFAULT;		if (regval[0] & 0x7) {		    printk("Error: configure_shub_stats: unaligned address 0x%016lx\n", regval[0]);		    return -EINVAL;		}		shub_mmr_write(cnode, (shubreg_t)regval[0], regval[1]);	}	return 0;}static intcapture_shub_stats(cnodeid_t cnode, uint32_t *counts){	int 		i;	for (i=0; i < SHUB_NUM_ECF_REGISTERS; i++) {		counts[i] = shub_mmr_read32(cnode, shub_perf_counts_regs[i]);	}	return 0;}static intshubstats_ioctl(struct inode *inode, struct file *file,        unsigned int cmd, unsigned long arg){        cnodeid_t       cnode;        uint64_t        longarg;        devfs_handle_t  d;	int		nasid;        if ((d = devfs_get_handle_from_inode(inode)) == NULL)                return -ENODEV;        cnode = (cnodeid_t)hwgraph_fastinfo_get(d);        switch (cmd) {	case SNDRV_SHUB_CONFIGURE:		return configure_shub_stats(cnode, arg);		break;	case SNDRV_SHUB_RESETSTATS:		reset_shub_stats(cnode);		break;	case SNDRV_SHUB_INFOSIZE:		longarg = sizeof(shub_perf_counts);		if (copy_to_user((void *)arg, &longarg, sizeof(longarg))) {		    return -EFAULT;		}		break;	case SNDRV_SHUB_GETSTATS:		capture_shub_stats(cnode, shub_perf_counts);		if (copy_to_user((void *)arg, shub_perf_counts,				       	sizeof(shub_perf_counts))) {		    return -EFAULT;		}		break;	case SNDRV_SHUB_GETNASID:		nasid = cnodeid_to_nasid(cnode);		if (copy_to_user((void *)arg, &nasid,				       	sizeof(nasid))) {		    return -EFAULT;		}		break;	default:		return -EINVAL;	}	return 0;}struct file_operations shub_mon_fops = {	        ioctl:          shubstats_ioctl,};

⌨️ 快捷键说明

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