[comp.unix.ultrix] How do you identify VAX/PMAX cpu's from software?

dan@asihub.UUCP (Dan O'Neill) (05/27/89)

Is there a way to determine the class of a VAX or PMAX cpu under
Ultrix?  We would like to be able to tell the difference between a
VAXstation 3200, VAXstation 3600, VAXstation 3100 and a DECstation
3100 (pmax) from within a program.  Any and all suggestions are
appreciated.
-- 
Dan O'Neill	dan@asihub.uucp    {uunet|ncr-sd}!asihub!dko
Automated Systems, Inc.  San Diego R&D

grr@cbmvax.UUCP (George Robbins) (05/29/89)

In article <105@asihub.UUCP> dan@asihub.UUCP (Dan O'Neill) writes:
> Is there a way to determine the class of a VAX or PMAX cpu under
> Ultrix?  We would like to be able to tell the difference between a
> VAXstation 3200, VAXstation 3600, VAXstation 3100 and a DECstation
> 3100 (pmax) from within a program.  Any and all suggestions are
> appreciated.

Assuming you really want to do such a disgusting and questionable thing,
you might take a look at /etc/sizer (man sizer).  You could create a
pipe to it and see what it returns.  Apparently it looks in the running
kernel to see what kind of machine the kernel thinks it's running on,
though there seems to be a lot of other silliness going on.

I don't know what this program does on the PMAX or on other than VAXen.
It doesn't, for example, distinguish between 780's and 785's or 8600's
and 8650's so it may in general not bother to distingush systems having
compatible programming models and I/O architecture.  It does apparently
know about display types for workstations, though.

-- 
George Robbins - now working for,	uucp: {uunet|pyramid|rutgers}!cbmvax!grr
but no way officially representing	arpa: cbmvax!grr@uunet.uu.net
Commodore, Engineering Department	fone: 215-431-9255 (only by moonlite)

fkittred@bbn.com (Fletcher Kittredge) (05/30/89)

In article <105@asihub.UUCP> dan@asihub.UUCP (Dan O'Neill) writes:
> Is there a way to determine the class of a VAX or PMAX cpu under
> Ultrix?  We would like to be able to tell the difference between a
> VAXstation 3200, VAXstation 3600, VAXstation 3100 and a DECstation
> 3100 (pmax) from within a program.  Any and all suggestions are
> appreciated.

Well, I don't have access to all of these systems, so this is a guess.  Try
the uname() system call and check the resulting structure.  If DEC
did a smart implementation, then the resulting information should tell
you what you need.  At minimum it should at least tell you if
your CPU is a MIPS or a VAX chip and the name and version of the O/S.

regards,
fletcher
Fletcher E. Kittredge  fkittred@bbn.com

frank@croton.DEC.COM (Frank Wortner) (05/30/89)

In article <7005@cbmvax.UUCP>, grr@cbmvax.UUCP (George Robbins) writes:

> Subject: Re: How do you identify VAX/PMAX cpu's from software?

> Assuming you really want to do such a disgusting and questionable thing,
> you might take a look at /etc/sizer (man sizer).  [...]  Apparently it
> looks in the running kernel to see what kind of machine the kernel
> thinks it's running on, though there seems to be a lot of other
> silliness going on.
> 
> I don't know what this program does on the PMAX or on other than VAXen.

Unfortunately, /etc/sizer does not exist on DECstation 3100 (PMAX), since the program is
VAX-specific.

Distinguishing a VAX from a PMAX can probably be best done at compile time.  Afterall,
you have to generate the proper binary for the proper machine.  As far as distiguishing
subtypes of CPUs, look in /usr/include/machine/hwconf.h on PMAXen and
/usr/include/machine/cpu.h on VAXen for information.  Those files contain macros for
processor type identification.

Regards,

						Frank Wortner
						Ultrix Resource Center
						Digital Equipment Corp.
						frank@croton.dec.com

Opinions expressed here are mine alone.  Feel free to share them.

frank@croton.DEC.COM (Frank Wortner) (05/30/89)

In article <40619@bbn.COM>, fkittred@bbn.com (Fletcher Kittredge) writes:

> In article <105@asihub.UUCP> dan@asihub.UUCP (Dan O'Neill) writes:
> > Is there a way to determine the class of a VAX or PMAX cpu under
> > Ultrix?  We would like to be able to tell the difference between a
> > VAXstation 3200, VAXstation 3600, VAXstation 3100 and a DECstation
> > 3100 (pmax) from within a program.  Any and all suggestions are
> > appreciated.
> 
> Well, I don't have access to all of these systems, so this is a guess.  Try
> the uname() system call and check the resulting structure.  If DEC
> did a smart implementation, then the resulting information should tell
> you what you need.  At minimum it should at least tell you if
> your CPU is a MIPS or a VAX chip and the name and version of the O/S.
> 

Fletcher, you are right.  Ultrix uname does exactly the minimum you describe.
Unfortunately, it does not descriminate amoung the various CPU implementations.
That is, uname will say that the machine is a VAX, but nothing more.  It could
be a 780, 3600, or whatever.  I'm afraid that bit-twiddling of magic words obtained
from the kernel is needed to get more information.

Regards,

						Frank

All opinions expressed are mine.  They can be yours for a small fee.

art@dinorah.wustl.edu (Arthur B. Smith) (05/31/89)

In article <1241@riscy.dec.com>, frank@croton.DEC.COM (Frank Wortner) writes:
> In article <7005@cbmvax.UUCP>, grr@cbmvax.UUCP (George Robbins) writes:
> 
> Unfortunately, /etc/sizer does not exist on DECstation 3100 (PMAX), since 
> the program is VAX-specific.
> 
> Distinguishing a VAX from a PMAX can probably be best done at compile 
> time.  Afterall, you have to generate the proper binary for the proper 
> machine.  As far as distiguishing subtypes of CPUs, look in 
> /usr/include/machine/hwconf.h on PMAXen and /usr/include/machine/cpu.h 
> on VAXen for information.  Those files contain macros for processor type 
> identification.
>
Oh yuck.  I generate the proper binary for the proper machine by running my
(identical) makefile on the appropriate machine.  Usually that makefile is
identical by virtue of being a symbolic link via NFS, so don't get any ideas
about "nearly" identical makefiles.  I know I can give command line arguments
to make, but I try to make it policy that all I ever need to say is "make all".

The solution for distinguishing subtypes of CPU's is no better.  Why should
one have to look in different files for equivalent information.  Come on, guys,
some of us are trying to develop software that will help sell your systems,
you should be making it easier for us, not harder!  

There should be a simple system call that identifies the hardware and
software, both by major classes (VAX vs. PMAX, Ultrix vs. VMS) and
specifics (780 vs. uVAX II, or even 780 vs. 785, if possible, and OS
Version number).  Surely that information HAS to be in the kernel, why
not write a quick easy system call that gets that info. out?  What?
You say that it would have to be radically different for each
hardware/software platform?  That's your problem (or at least, it
should be yours, not the application developer's)! 

        Rant, rant rant,
	art smith (art@dinorah.wustl.edu, ...!uunet!wucs1!dinorah!art)
	

grr@cbmvax.UUCP (George Robbins) (05/31/89)

In article <1242@riscy.dec.com> frank@croton.DEC.COM (Frank Wortner) writes:
> In article <40619@bbn.COM>, fkittred@bbn.com (Fletcher Kittredge) writes:
> > In article <105@asihub.UUCP> dan@asihub.UUCP (Dan O'Neill) writes:
> > > Is there a way to determine the class of a VAX or PMAX cpu under
> > > Ultrix?...
> > 
> > Well, I don't have access to all of these systems, so this is a guess.  Try
> > the uname() system call and check the resulting structure...
> 
> Fletcher, you are right.  Ultrix uname does exactly the minimum you describe.
> Unfortunately, it does not descriminate amoung the various CPU implementations
> That is, uname will say that the machine is a VAX, but nothing more.  It could
> be a 780, 3600, or whatever.  I'm afraid that bit-twiddling of magic words
> obtained from the kernel is needed to get more information.

Not too mysterious, the kernel variables _cpu, _cpu_subtype and mayhaps
_cpu_sub_subtype seem to be the basic story.  Values for cpu and subtype
show up in /sys/vax/cpu.h.  Of course there's no promise that the values
in a putative /sys/pmax/cpu.h don't overlap.

To emphasize an earlier point, this is not the kind of stuff that an
application should be looking at.  Unless there's some really good reason
for peeking under the skirts, the application should be insensitive to
cpu type or should a least view the matter as on of attributes rather
than instances.

-- 
George Robbins - now working for,	uucp: {uunet|pyramid|rutgers}!cbmvax!grr
but no way officially representing	arpa: cbmvax!grr@uunet.uu.net
Commodore, Engineering Department	fone: 215-431-9255 (only by moonlite)

frank@riscy.dec.com (Frank Wortner) (05/31/89)

I've cooked up a short program to identify CPUs --- just to show 1) it
can be done, and 2) it is not hard.  Compile the program thusly on
either VAX or DECstation:  cc cputype.c.

Have fun!
						Frank

---------------------------------Cut Here------------------------------

/*
 *	cputype.c:	Print the CPU type and memory size on stdout.
 */


#include <nlist.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

#include <sys/types.h>
#include <sys/file.h>
#include <sys/cpudata.h>
#include <sys/config.h>


#include <machine/param.h>

#ifdef	vax
#	include <machine/cpu.h>
#endif
#ifdef	mips
#	include <machine/hwconf.h>
#endif


/*
 *	The kernal data structures we are interested in.
 */
struct nlist	namelist[] = {
/*
 *	Names of things and other "static" data.
 */
	{ "_physmem" },		/* NM_PHYSMEM */
	{ "_cpu" },		/* NM_CPU */
	{ "_cpudata" },		/* NM_CPUDATA */
	{ "_cpu_subtype" },	/* NM_CPU_SUBTYPE */
/*
 *	This will only be used by the MIPS based systems,
 *	but it doesn't need to be #ifdef'd.
 */
	{ "_cpu_systype" },	/* NM_CPU_SYSTYPE */
/*
 *	End of list.
 */
	{ 0 }
};

#define NM_PHYSMEM 0
#define NM_CPU     1
#define NM_CPUDATA 2
#define NM_CPU_SUBTYPE 3
#define NM_CPU_SYSTYPE 4

/*
 *	These arrays will allow cpu.c to get a CPU string from
 *	a type and subtype.
 */
struct cpu_type {
	int	type;
	char	*string;
	struct cpu_type *subtype;
};

#ifdef	vax
struct cpu_type vax8200[] = {
	ST_8200, "VAX 8200/8250", NULL,
	ST_8300, "VAX 8300/8350", NULL,
	ST_8400, "VAX 8400/8450", NULL,
	{ 0, 0, 0, },
};

struct cpu_type vax8800[] = {
	ST_8500, "VAX 8500/8530", NULL,
	ST_8550, "VAX 8550", NULL,
	ST_8700, "VAX 8700", NULL,
	ST_8800, "VAX 8800", NULL,
	{ 0, 0, 0, },
};

struct cpu_type microvax2[] = {
	ST_MVAXII,  "MicroVAX/VAXstation II",   NULL,
	ST_VAXSTAR, "MicroVAX/VAXstation 2000", NULL,
	{ 0, 0, 0, },
};

struct cpu_type cpu_types[] = {
/*
 *	The VAX list.
 */
	VAX_780,  "VAX 11/780 or 11/785", NULL,
	VAX_750,  "VAX 11/750 or 11/751", NULL,
	VAX_730,  "VAX 11/730 or 11/725", NULL,
	VAX_8600, "VAX 8600/8650", NULL,
	VAX_8200, "VAX 8200/8250/8300/8350", vax8200,
	VAX_8800, "VAX 8800/8700/8550/8530/8500", vax8800,
	MVAX_I,   "MicroVAX I", NULL,
	MVAX_II,  "MicroVAX/VAXstation II", microvax2,
/*
 *	Future CPU types will need to be #ifdef'd as these
 *	are.  This lets the data be updated for newer versions
 *	but still be backward compatiable.
 */
#ifdef	C_VAX
	C_VAX,    "MicroVAX/VAXstation 3200/3500/3600", NULL,
#endif
#ifdef	VAX_6200
	VAX_6200, "VAX 6210/6220/6230/6240", NULL,
#endif
#ifdef	C_VAXSTAR
	C_VAXSTAR, "VAXstation 3100", NULL,
#endif
#ifdef	VAX_8820
	VAX_8820, "VAX 8820/8830/8840", NULL,
#endif
};
#endif

/*
 *	The MIPS list.
 */
#ifdef	mips
struct cpu_type cpu_types[] = {
	{ PMAX, "DECstation 3100", NULL, },
	{ 0, 0, 0, },
} ;
#endif

static int kmem;

/*
 *	Functions which don't return (int).
 */
char	*str_cpuid();


void	nlist(),
	fatal(),
	readk();



main()
{
  cpu_names();
  exit (0);
}

/*
 *	Print something about the CPU.
 */
static	cpu_names()
{
	int	sid, physmem ;
	long	subtype = -1 ;
	caddr_t	addr ;

	sid = getsid() ;

	/*
	 *	Get the amount of physical memory.
	 */
	if((addr = (caddr_t)namelist[NM_PHYSMEM].n_value) == 0 ) {
		warning("Can't get physical memory size.\n") ;
		return ;
	}
	else
		readk((long)addr, (char *)&physmem, sizeof(physmem)) ;

#ifdef	vax
	subtype = get_cpu_subtype(addr);
#endif
#ifdef	mips
	subtype = GETCPUTYPE(sid) ;
#endif

	printf("%s with %d bytes of memory.\n", str_cpuid(sid, subtype),
		physmem * NBPG) ;
}


/*
 *	Local version of a system call to get the contents of the SID
 *	register.  This function constructs a number which looks like
 *	the contents of a CPU SID register.
 *
 *	It is a feature of the MicroVAX architecture that this function
 *	will always return the correct SID.
 */
getsid()
{
/*
 *	Data for the two architectures.
 */
#ifdef	vax
	int	nm_cpu ;
	union	cpusid cpu ;
#endif
#ifdef	mips

	int	cpu_systype ;
#endif

	open_names();
/*
 *	The architecture dependent code.
 */
#ifdef	vax
	readk((long)namelist[NM_CPU].n_value, (char *)&nm_cpu, sizeof(nm_cpu)) ;

	cpu.cpuany.cp_type = nm_cpu ;

	return cpu.cpusid ;
#endif

#ifdef	mips
	readk((long)namelist[NM_CPU_SYSTYPE].n_value, (char *)&cpu_systype,
		sizeof(cpu_systype)) ;

	return cpu_systype ;
#endif
}


/*
 *	Set up the namelist and open the kernel so we can get
 *	to the names.
 */
open_names(op)
{
	/*
	 *	Initialize the namelist, nlist(x) doesn't return
	 *	anything to signify an error.
	 */
	(void)nlist("/vmunix", namelist) ;

	/*
	 *	Open memory.
	 */
	if((kmem = open("/dev/kmem", O_RDONLY, 0)) == -1 )
		fatal("Can't open /dev/kmem: ") ;
}

/*
 *	Try to close /dev/kmem.
 */
close_names(op)
{
	if( close(kmem) == -1 )
		fatal("Can't close /dev/kmem: ") ;
}



/*
 *	Get the CPU subtype.
 */
int get_cpu_subtype(addr)
     caddr_t addr;
{
  int subtype;
  
  if((addr = (caddr_t)namelist[NM_CPU_SUBTYPE].n_value) == 0 )
    subtype = -1 ;
  else
    readk((long)addr, (char *)&subtype, sizeof(long)) ;
  return (subtype);
}


/*
 *	Seek to "where" in the kernel and read "size" bytes
 *	into the space at "addr".
 */
void readk(where, addr, size)
long	where ;
char	*addr ;
int	size ;
{
	long	lseek() ;

	if( lseek(kmem, where, L_SET) == -1 )
		fatal("Can't lseek in /dev/kmem: ");

	if( read(kmem, addr, size) == -1 )
		fatal("Can't read from /dev/kmem: ");
}



/*
 *	Functions and data to take the CPU id and turn it into something
 *	"meaningful".
 */
char	*str_cpuid(ident, subtype)
int	ident ;
long	subtype ;
{
#ifdef	vax
	union cpusid cpu ;
#endif
	int	type ;
	struct cpu_type *sp, *tp ;

	tp = &cpu_types[0] ;

/*
 *	This is the VAX version of how to turn the system
 *	id into a system name.
 */
#ifdef	vax
	cpu.cpusid = ident ;
	type = cpu.cpuany.cp_type ;
#endif

/*
 *	On the mips we can get everything from the cpu_systype.
 */
#ifdef	mips
	type = GETSYSTYPE(ident) ;
#endif

	while( tp->string != NULL ) {
		if( tp->type == type ) {
			/*
			 *	If there isn't a subtype list return
			 *	the string for the type.
			 */
			if((sp = tp->subtype) == NULL )
				return tp->string ;

			/*
			 *	Else...  Walk the the subtype list
			 *	looking for a matching subtype.
			 */
			while( sp->string != NULL ) {
				if( sp->type == subtype )
					return sp->string ;

				sp++ ;
			}

			/*
			 *	If there isn't a subtype match return
			 *	the type string.
			 */
			return tp->string ;
		}

		tp++ ;
	}

	return "Unknown CPU type" ;
}



void fatal(str)
     char *str;
{
  perror(str);
  exit(1);
}

warning(str)
{
  fprintf(stderr, "%s\n", str);
}

frank@croton.DEC.COM (Frank Wortner) (05/31/89)

Since I was in a hurry last night --- I had to catch a train --- I did a hurry-up job
on the cputype.c program posting, and I did not give proper credit to Alan Rollow of DEC
for his CPU-id subroutines.  My apologies.

The program does identity those CPUs that can be distinguished, should you really need to
do so.  While there is conditional compilation in cputype.c, no special flags need be
passed to the compiler to differentiate VAX from RISC versions.  If I had had more time,
I would have tried to isolate more of the machine-dependant code.

Regards,

						Frank

mrm@sceard.COM (M.R.Murphy) (06/01/89)

In article <743@dinorah.wustl.edu> art@dinorah.wustl.edu (Arthur B. Smith) writes:
!In article <1241@riscy.dec.com>, frank@croton.DEC.COM (Frank Wortner) writes:
!> In article <7005@cbmvax.UUCP>, grr@cbmvax.UUCP (George Robbins) writes:
!> 
!> Unfortunately, /etc/sizer does not exist on DECstation 3100 (PMAX), since 
!> the program is VAX-specific.
!> 
!> Distinguishing a VAX from a PMAX can probably be best done at compile 
!> time.
[many lines deleted in the interest of bandwidth]

What you do is look at the front panel of the computer (or the invoice
for the system) and then write a shell script /etc/what_kind_of_system_this_is
that echos said information. This then has the advantage of being able to
be run on lots of different kinds of systems. Even to be extended to the
determination of cabinet configuration, color, or line voltage...

Why, the concept can even be used in (shudder) VMS. The design of the format
for the information from the script is left as an excercise for the reader.

:-)
---
Mike Murphy  Sceard Systems, Inc.  544 South Pacific St. San Marcos, CA  92069
mrm@Sceard.COM        {hp-sdd,nosc,ucsd,uunet}!sceard!mrm      +1 619 471 0655

michaud@vaxcpu.nac.dec.com (Jeff Michaud) (06/02/89)

> What you do is look at the front panel of the computer (or the invoice
> for the system) and then write a shell script /etc/what_kind_of_system_this_is
> that echos said information. This then has the advantage of being able to
> be run on lots of different kinds of systems. Even to be extended to the
> determination of cabinet configuration, color, or line voltage...

	Take a look at the script /bin/machine on the DS3100 (PMAX).  It echos
	the machine type as `mips'.  Hopefully the next release of ULTRIX on
	the VAX will have such a script also but will echo `vax'.  For now though

		# Assume "vax" by default
		set Machine = "vax"
		if( -x /bin/machine ) set Machine = `/bin/machine`

	Not exactly a "/etc/what_kind_of_system_this_is", but does allow you to cleanly
	ifdef things like your .login and .cshrc.

Jeff		#include <standard/disclaimer.h>

mitch@batcomputer.tn.cornell.edu (Mitch Collinsworth) (06/02/89)

In article <893@sceard.COM> mrm@sceard.COM (0040-M.R.Murphy) writes:

>What you do is look at the front panel of the computer (or the invoice
>for the system) and then write a shell script /etc/what_kind_of_system_this_is
>that echos said information. This then has the advantage of being able to
>be run on lots of different kinds of systems. Even to be extended to the
>determination of cabinet configuration, color, or line voltage...
>
>Why, the concept can even be used in (shudder) VMS. The design of the format
>for the information from the script is left as an excercise for the reader.

VMS has a system service call that can be used to get all sorts of useful
information including the CPU type, the VAX model name, the number of CPUs
and how many are active, etc.  Perhaps Ultrix could use a similar function.

-Mitch Collinsworth
 mitch@squid.tn.cornell.edu