File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / mem / locate.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:30:15 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21

/* 
	This routine locate the error at the board level based on 3 possible
	configurations set in OPTIONS:
		- bit 4 reset: 1Mb boards only, numbered 0-n
		- bit 4   set: 4Mb boards only, numbered 0-n
		- bit 5   set: 20 Mb of "mixed" boards configured as: 
			boards 0-3 => 4 4Mb boards, addr 00-16 Mb
			boards 4-7 => 4 1Mb boards, addr 17-20 Mb
*/
#include "definitions"
extern struct OPTIONS OPTIONS;

extern	long	maxmem,endprog,scb;
extern	long	eccloc(), cycle,test_no,errcnt;
extern	long	loop_flg,hlt_flg,prt_flg;

extern struct tmp_mcbr{
    unsigned                   :2;
    unsigned	syndrome       :7;
    unsigned	chk_bits       :7;
    unsigned	      	      :14;
    unsigned   versabus_type   :2;
} tmp_mcbr;

extern struct tmp_mear{
    unsigned 	mear	      :16;
    unsigned		      :10;
    unsigned	ber	      :1;
    unsigned	erm	      :1;
    unsigned	axe    	      :1;
    unsigned	err_code      :3;
} tmp_mear; 

struct mcbr{
    unsigned                   :18;
    unsigned	synd_bits      :7;
    unsigned	check_bits     :7;
};

struct mer{
    unsigned		      :16;
    unsigned		      :10;
    unsigned	ber	      :1;
    unsigned	erm	      :1;
    unsigned	axe    	      :1;
    unsigned	err_code      :3;
};

struct mcr{
    unsigned		   :16;
    unsigned	err_count  : 8;
    unsigned	clr_error  : 1;
    unsigned	clr_count  : 1;
    unsigned	init	   : 1;
    unsigned               : 1;
    unsigned	diag_read  : 1;
    unsigned	diag_writ  : 1;
    unsigned	correction : 1;	/* Enable Error Correction */
    unsigned	detection  : 1;	/* Enable Error Detection */
};

long *CPCR = (long *)0xffffb028;	/* Ptr to CP Control register */


locate(addr,exp,act)
long addr,exp,act;
{
  long intl, board,b1, bank;
  register struct mcr *MCR = (struct mcr *)0xffffb000;
  register struct mer *MER = (struct mer *)0xffffb020;
  register struct mcbr *MCBR = (struct mcbr *)0xffffb008;
     if(OPTIONS.mixed) {
	if(( addr & 0x3fffffff ) <= 0x00ffffff ) {
		if (!(loc4mb(addr,&board,&bank,&intl))) 
		return(0); }
	else {
		if (!(locboard(addr,&board,&bank,&intl))) 
		 return(0);
		else
		 board = ( board - 16 ) + 4;
/* - 16 + 4 => 4x4 Mb in 4 boards 0-3 ( locboard assumes n 1Mb boards 0-n) */
	     }
     }
     else  {

	if(OPTIONS.fourmb) {
		if (!(loc4mb(addr,&board,&bank,&intl))) 
		return(0); }
	else {
		if (!(locboard(addr,&board,&bank,&intl))) 
		return(0); }
     }
	intl = *CPCR & 3;	/* Read Memory Interleave status */
	if (intl) {
		if (intl==1) intl=2;
			else intl = 4;
		}
	writes("\n"); writed(intl);writes(" ways interleave.");
	writes("\nBoard # "); writed(board);
	writes(", Bank # "); writed(bank,1);
	writes("\nIC number(s) : ");
	locic(bank,exp,act);
}

char *names[4] = {
	" U7"," U5"," U3"," U1" 
};

locic(bk,exp,act)
long bk, exp, act;
{	register long ix, bad, bit, b2;
	char *this, str[4];

	for(ix=0;ix<3;ix++) str[ix] = names[bk][ix];
	str[3] = '\0';
	this = str;
	bad = exp ^ act;		/* Exclusive OR */
	bit = 1;
	writes("\n");
	for(ix=0;ix<32; ix++, bit <<= 1) {
		if (ix == 16) this[2]++;	/* Second row */
		if (bad & bit) {
			/* Bit in error */
			b2 = ix;
			if (ix > 15) b2 = ix-16;
			writes(this);
			b2 += 2;
			if (b2 >= 10) { writes("1");
				b2 -= 10;
				}
			    else writes("0");
			pt_hex(b2,1);
			}
		}
	writes("\n");
}
/*
	locate board and bank for 1 mbyte memory array in n 1Mb boards 0-n
*/
locboard(addr,board,bank,intl)
long addr;
long *board, *bank,*intl;
{
  	register long inl, b1;
	writes("\n1 mb");
	inl = *CPCR & 3;	/* Read Memory Interleave status */
	*intl = inl;
	if (inl==2) {
		writes("\nInvalid memory interleave status : ");
		writeh(inl);
		return(0); }
	if (!inl) {
		/* Non_interleave */
		*board = (addr & 0x3ff00000) >> 20;
		*bank = (addr & 0xc0000) >> 18;
		}
	     else {
		if (inl==1) {
			/* 2 ways interleave */
			*board = (addr & 0x3fd00000) >> 20;
			b1 = (addr & 0x4) >> 2;
			*board |= b1;
			*bank = (addr & 0x180000) >> 19;
			*intl = 2;
			}
		    else  {
			/* 4 ways interleave */
			*board = (addr & 0x3fc00000) >> 20;
			b1 = (addr & 0xc) >> 2;
			*board |= b1;
			*bank = (addr & 0x300000) >> 20;
			*intl = 4;
			}
		}
	return(1);
}
/*
	locate board and bank for 4 mbyte memory array in n 4Mb boards 0-n
*/
loc4mb(addr,board,bank,intl)
long addr;
long *board, *bank,*intl;
{
  	register long inl, b1;
	writes("\n4 mb");

	inl = *CPCR & 3;	/* Read Memory Interleave status */
	*intl = inl;
	if (inl==2) {
		writes("\nInvalid memory interleave status : ");
		writeh(inl);
		return(0); }
	if (!inl) {
		/* Non_interleave */
		*board = (addr & 0x3fc00000) >> 22;
		*bank = (addr & 0x300000) >> 20;
		}
	     else {
		if (inl==1) {
			/* 2 ways interleave */
			*board = (addr & 0x3f800000) >> 22;
			b1 = (addr & 0x4) >> 2;
			*board |= b1;
			*bank = (addr & 0x600000) >> 21;
			*intl = 2;
			}
		    else  {
			/* 4 ways interleave */
			*board = (addr & 0x3f000000) >> 22;
			b1 = (addr & 0xc) >> 2;
			*board |= b1;
			*bank = (addr & 0xc00000) >> 22;
			*intl = 4;
			}
		}
	return(1);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.