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

📄 llsc4.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * * 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) 2000 Silicon Graphics, Inc. * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com) */#include <linux/config.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/smp.h>#include <linux/kernel_stat.h>#include <linux/mm.h>#include <linux/delay.h>#include <linux/string.h>#include <asm/efi.h>#include <asm/page.h>#include <linux/threads.h>extern void bringup_set_led_bits(u8 bits, u8 mask);#include "llsc4.h"#ifdef STANDALONE#include "lock.h"#endif#ifdef INTTESTstatic int	inttest=0;#endif/* * Test parameter table for AUTOTEST */typedef struct {	int	passes;	int	linecount;	int	linepad;} autotest_table_t;autotest_table_t autotest_table[] = {	{1000000,	2,	0x2b4		},	{1000000,	16,	0,		},	{1000000,	16,	4,		},	{1000000,	128,	0x44		},	{1000000,	128,	0x84		},	{1000000,	128,	0x200		},	{1000000,	128,	0x204		},	{1000000,	128,	0x2b4		},	{1000000,	2,	8*MB+0x2b4	},	{1000000,	16,	8*MB+0		},	{1000000,	16,	8*MB+4		},	{1000000,	128,	8*MB+0x44	},	{1000000,	128,	8*MB+0x84	},	{1000000,	128,	8*MB+0x200	},	{1000000,	128,	8*MB+0x204	},	{1000000,	128,	8*MB+0x2b4	},	{0}};/* * Array of virtual addresses available for test purposes. */typedef struct {	long	vstart;	long	vend;	long	nextaddr;	int	wrapcount;} memmap_t;memmap_t 	memmap[MAXCHUNKS];int		memmapx=0;typedef struct {	void	*addr;	long	data[16];	long	data_fc[16];} capture_line_t;typedef struct {	int	size;	void	*blockaddr;	void	*shadaddr;	long	blockdata[16];	long	shaddata[16];	long	blockdata_fc[16];	long	shaddata_fc[16];	long	synerr;} capture_t;/* * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and * the rest of the tables have to start at 1MB to skip PROM tables. */#define THREADPRIVATE(t)	((threadprivate_t*)(((long)mbase)+1024*1024+t*((sizeof(threadprivate_t)+511)/512*512)))#define k_capture		mbase->sk_capture#define k_go			mbase->sk_go#define k_linecount		mbase->sk_linecount#define k_passes		mbase->sk_passes#define k_napticks		mbase->sk_napticks#define k_stop_on_error		mbase->sk_stop_on_error#define k_verbose		mbase->sk_verbose#define k_threadprivate		mbase->sk_threadprivate#define k_blocks		mbase->sk_blocks#define k_iter_msg		mbase->sk_iter_msg#define k_vv			mbase->sk_vv#define k_linepad		mbase->sk_linepad#define k_options		mbase->sk_options#define k_testnumber		mbase->sk_testnumber#define k_currentpass		mbase->sk_currentpassstatic long		blocks[MAX_LINECOUNT];		/* addresses of data blocks */static control_t	*mbase;static vint		initialized=0;static unsigned int ran_conf_llsc(int);static int  rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int);static void dumpline(void *, char *, char *, void *, void *, int);static int  checkstop(int, int, uint);static void spin(int);static void capturedata(capture_t *, uint, void *, void *, int);static int  randn(uint max, uint *seed);static uint zrandom (uint *zranseed);static int  set_lock(uint *, uint);static int  clr_lock(uint *, uint);static void Speedo(void);int autotest_enabled=0;static int autotest_explicit_flush=0;static int llsctest_number=-1;static int errstop_enabled=0;static int fail_enabled=0;static int selective_trigger=0;static int __init autotest_enable(char *str){        autotest_enabled = 1;	return 1;}static int __init set_llscxflush(char *str){	autotest_explicit_flush = 1;	return 1;}static int __init set_llscselt(char *str){	selective_trigger = 1;	return 1;}static int __init set_llsctest(char *str){        llsctest_number = simple_strtol(str, &str, 10);	if (llsctest_number < 0 || llsctest_number > 15)		llsctest_number = -1;	return 1;}static int __init set_llscerrstop(char *str){        errstop_enabled = 1;	return 1;}static int __init set_llscfail(char *str){        fail_enabled = 8;	return 1;}static void print_params(void){	printk ("********* Enter AUTOTEST facility on master cpu *************\n");	printk ("  Test options:\n");	printk ("     llsctest=<n>\t%d\tTest number to run (all = -1)\n", llsctest_number);	printk ("     llscerrstop \t%s\tStop on error\n", errstop_enabled ? "on" : "off");	printk ("     llscxflush  \t%s\tEnable explicit FC in test\n", autotest_explicit_flush ? "on" : "off");	printk ("     llscfail    \t%s\tForce a failure to test the trigger & error messages\n", fail_enabled ? "on" : "off");	printk ("     llscselt    \t%s\tSelective triger on failures\n", selective_trigger ? "on" : "off");	printk ("\n");}__setup("autotest", autotest_enable);__setup("llsctest=", set_llsctest);__setup("llscerrstop", set_llscerrstop);__setup("llscxflush", set_llscxflush);__setup("llscfail", set_llscfail);__setup("llscselt", set_llscselt);extern inline voidflush_buddy(void *p){	long	lp;	if (autotest_explicit_flush)  {		lp = (long)p;		lp ^= 0x40;		asm volatile ("fc %0" :: "r"(lp) : "memory");		ia64_sync_i();		ia64_srlz_d();	}}static intset_lock(uint *lock, uint id){	uint	old;	flush_buddy(lock);	old = cmpxchg_acq(lock, 0, id);	return (old == 0);}static intclr_lock(uint *lock, uint id){	uint	old;	flush_buddy(lock);	old = cmpxchg_rel(lock, id, 0);	return (old == id);}static voidzero_lock(uint *lock){	flush_buddy(lock);	*lock = 0;}/*------------------------------------------------------------------------+| Routine  :  ran_conf_llsc - ll/sc shared data test                      || Description: This test checks the coherency of shared data              |+------------------------------------------------------------------------*/static unsigned intran_conf_llsc(int thread){	private_t	pval;	share_t		sval, sval2;	uint		vv, linei, slinei, sharei, pass;	long		t;	lock_t		lockpat;	share_t		*sharecopy;	long		verbose, napticks, passes, linecount, lcount;	dataline_t	*linep, *slinep;	int		s, seed;	threadprivate_t	*tp;	uint		iter_msg, iter_msg_i=0;	int		vv_mask;	int		correct_errors;	int		errs=0;	int		stillbad;	capture_t	capdata;	private_t	*privp;	share_t		*sharep;	linecount = k_linecount;	napticks = k_napticks;	verbose = k_verbose;	passes = k_passes;	iter_msg = k_iter_msg;	seed = (thread + 1) * 647;	tp = THREADPRIVATE(thread);	vv_mask = (k_vv>>((thread%16)*4)) & 0xf;	correct_errors = k_options&0xff;	memset (&tp->private, 0, sizeof(tp->private));	memset (&capdata, 0, sizeof(capdata));	for (pass = 1; passes == 0 || pass < passes; pass++) {		lockpat = (pass & 0x0fffffff) + (thread <<28);		tp->threadpasses = pass;		if (checkstop(thread, pass, lockpat))			return 0;		iter_msg_i++;		if (iter_msg && iter_msg_i > iter_msg) {			printk("Thread %d, Pass %d\n", thread, pass);			iter_msg_i = 0;		}		lcount = 0;		/*		 * Select line to perform operations on.		 */		linei = randn(linecount, &seed);		sharei = randn(2, &seed);		slinei = (linei + (linecount/2))%linecount;		/* I dont like this - fix later */		linep = (dataline_t *)blocks[linei];		slinep = (dataline_t *)blocks[slinei];		if (sharei == 0)			sharecopy = &slinep->share0;		else			sharecopy = &slinep->share1;		vv = randn(4, &seed);		if ((vv_mask & (1<<vv)) == 0)			continue;		if (napticks) {			t = randn(napticks, &seed);			udelay(t);		}		privp = &linep->private[thread];		sharep = &linep->share[sharei];				switch(vv) {		case 0:			/* Read and verify private count on line. */			pval = *privp;			if (verbose)				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);			if (pval != tp->private[linei]) {				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));				stillbad = (*privp != tp->private[linei]);				if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {					return 1;				}				if (correct_errors) {					flush_buddy(privp);					tp->private[linei] = *privp;				}				errs++;			}			break;		case 1:			/* Read, verify, and increment private count on line. */			pval = *privp;			if (verbose)				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);			if (pval != tp->private[linei]) {				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));				stillbad = (*privp != tp->private[linei]);				if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {					return 1;				}				errs++;			}			pval++;			flush_buddy(privp);			*privp = pval;			tp->private[linei] = pval;			break;		case 2:			/* Lock line, read and verify shared data. */			if (verbose)				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);			lcount = 0;			while (LOCK(sharei) != 1) {				if (checkstop(thread, pass, lockpat))					return 0;				if (lcount++>1000000) {					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));					stillbad = (GETLOCK(sharei) != 0);					rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);					return 1;				}				if ((lcount&0x3fff) == 0)					udelay(1000);			}			sval = *sharep;			sval2 = *sharecopy;			if (pass > 12 && thread == 0 && fail_enabled == 1)				sval++;			if (sval != sval2) {				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));				stillbad = (*sharep != *sharecopy);				if (!stillbad && *sharep != sval && *sharecopy == sval2)					stillbad = 2;				if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {					return 1;				}				if (correct_errors)					*sharep = *sharecopy;				errs++;			}			if ( (s=UNLOCK(sharei)) != 1) {				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);				stillbad = (GETLOCK(sharei) != lockpat);				if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad))					return 1;				if (correct_errors)					ZEROLOCK(sharei);					errs++;			}			break;		case 3:			/* Lock line, read and verify shared data, modify shared data. */			if (verbose)				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);			lcount = 0;			while (LOCK(sharei) != 1) {				if (checkstop(thread, pass, lockpat))					return 0;				if (lcount++>1000000) {					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));					stillbad = (GETLOCK(sharei) != 0);					rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);					return 1;				}				if ((lcount&0x3fff) == 0)					udelay(1000);			}			sval = *sharep;			sval2 = *sharecopy;			if (sval != sval2) {				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));				stillbad = (*sharep != *sharecopy);				if (!stillbad && *sharep != sval && *sharecopy == sval2)					stillbad = 2;				if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {					return 1;				}				errs++;			}			flush_buddy(sharep);			*sharep = lockpat;			flush_buddy(sharecopy);			*sharecopy = lockpat;			if ( (s=UNLOCK(sharei)) != 1) {				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);				stillbad = (GETLOCK(sharei) != lockpat);				if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad))					return 1;				if (correct_errors)					ZEROLOCK(sharei);					errs++;			}			break;		}	}	return (errs > 0);}static voidtrigger_la(long val){	long	*p;	p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */	*p = val;}static longgetsynerr(void){	long	err, *errp;	errp = (long*)0xc0000e0000000340L;	/* SYN_ERR */	err = *errp;	if (err)		*errp = -1L;	return (err & ~0x60);}static intrerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int linei, int exp, int found, int stillbad){

⌨️ 快捷键说明

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