129 lines
5.9 KiB
Rexx
129 lines
5.9 KiB
Rexx
/* CPUID -- Display CPU information from REXX */
|
|
/* article in TSO TIMES, Fall 1993, by John Andrisan */
|
|
/* of IBM ISSC subdivision in Long Beach California */
|
|
/*********************************************************************/
|
|
/* A TSO REXX Exec to get information aobut CPUs from the MVS */
|
|
/* control blocks: DVT, SMCA, CSD, PCCAVT, and PCCA; then show CPU */
|
|
/* number, id serial number, type, SMF id letter, and anything else */
|
|
/* that looks interesting. */
|
|
/* */
|
|
/* The control block chain that I want to follow: */
|
|
/* location 10x --> CVT */
|
|
/* CVT+C4x --> SMCA */
|
|
/* SMCA+16 contains the SMF id */
|
|
/* CVT+294x --> CSD */
|
|
/* CSD+4, +8 and + 10 contain */
|
|
/* some interesting cpu counts */
|
|
/* CVT+2FCx --> PCCAVT */
|
|
/* PCCAVT+0 --> PCCA for CPU 0 */
|
|
/* PCCAVT+4 --> PCCA for CPU 1 */
|
|
/* ... etc. */
|
|
/* PCCAVT+60 --> PCCA for CPU 15 */
|
|
/* PCCA+4 contains the cpu id, serial#, type */
|
|
/* PCCA+24 --> virtual PSA */
|
|
/* PCCA+28 --> real PSA */
|
|
/*********************************************************************/
|
|
/* ---------begin available "The REXX Macros Toolbox" only portion*/
|
|
"CLS" /* clear screen*/
|
|
say '----- information obtained via WHICH CPU ------'
|
|
"WHICH CPU"
|
|
say ' '
|
|
say '----- information from CPUID -- Display CPU information'
|
|
/* ------------ end available "The REXX Macros Toolbox" only portion*/
|
|
arg what .
|
|
if what='?' then do /* offer the user some help */
|
|
say ' use: COMMAND ===> CPUID'
|
|
say ' No parms are required'
|
|
say ' You will be shown the SMF id letter defining this system,'
|
|
say ' the CPU id, serial number, and CPU type of each CPU,'
|
|
say ' This exec (CPUID) only works on TSO.'
|
|
end
|
|
if address() /='TSO' then do
|
|
say 'This exec only works in MVS/TSO.'
|
|
exit 4
|
|
end
|
|
call init /* set up some constants */
|
|
CVT=storage('10',4)
|
|
CVT=bitand(CVT,'7FFFFFFF'x) /* zero high bit */
|
|
SMCA=storage(d2x(c2d(CVT)+x2d('C4')),4) /* get to SMCA */
|
|
SMCA=bitand(SMCA,'7FFFFFFF'x)
|
|
SMCASID=storage(d2x(c2d(SMCA)+16),4)
|
|
say 'SMF id=' SMCASID
|
|
CSD=storage(d2x(c2d(CVT)+x2d('294')),4) /* get to CSD */
|
|
CSD=bitand(CSD,'7FFFFFFF'x) /* zero high bit */
|
|
/* the counts shown next may change whil you run*/
|
|
nr_cpus=c2d(storage(d2x(c2d(CSD)+10),2)) /* get nr cur alive */
|
|
say 'nr cpus currently alive:' nr_cpus /* whatever that is */
|
|
job_avail_cpus=x2b(c2x(storage(d2x(c2d(csd)+4),2)))
|
|
say count_bits(job_avail_cpus) 'available for jobs'
|
|
srb_avail_cpus=x2b(c2x(storage(d2x(c2d(csd)+8),2)))
|
|
say count_bits(srb_avail_cpus) 'available for srbs'
|
|
cur_alive_cpus=x2b(c2x(storage(d2x(c2d(CSD)+10),2)))
|
|
say count_bits(cur_alive_cpus) 'currently alive'
|
|
say ' '
|
|
PCCAAVT=storage(d2x(c2d(CVt)+x2d('2FC')),4) /* get to PCCAVT */
|
|
PCCAAVT=bitand(PCCAAVT,'7FFFFFFF'x) /* zero high bit*/
|
|
|
|
say '-----CPU-------------- PSA PSA '
|
|
say '# ver id serial type vaddr raddr status:'
|
|
do i=0 to 60 by 4
|
|
PCCA=storage(d2x(c2d(PCCAAVT)+i),4) /* get the i-th PCCA */
|
|
PCCA=bitand(PCCA,'7FFFFFFF'x) /* zero high bit */
|
|
if PCCA=='00000000'x then iterate i /* avoid empty entry */
|
|
info=storage(c2x(PCCA),32)
|
|
if substr(job_avail_cpus,i%4+1,1)='1' then jobs='jobs'
|
|
else jobs='no-jobs'
|
|
if substr(srb_avail_cpus,i%4+1,1)='1' then srbs='srbs'
|
|
else jobs='no-srbs'
|
|
if substr(cur_alive_cpus,i%4+1,1)='1' then alive='alive'
|
|
else alive='no-alive'
|
|
/* as run "The REXX Macros Toolbox" 1993/12/16
|
|
SMF id= H901
|
|
nr cpus currently alive: 5
|
|
5 available for jobs
|
|
5 available for srbs
|
|
2 currently alive
|
|
|
|
-----CPU-------------- PSA PSA
|
|
# ver id serial type vaddr raddr status:
|
|
00 52 0 12495 3090 8000F6F0 00157240 jobs srbs no-alive
|
|
01 52 1 12495 3090 7800F9F0 00134030 jobs srbs no-alive
|
|
02 52 2 12495 3090 0000F980 0002F040 jobs srbs no-alive
|
|
03 52 3 12495 3090 0000F960 00068040 jobs srbs no-alive
|
|
04 52 4 12495 3090 1000F7F0 000A2040 jobs srbs no-alive
|
|
05 a: 9 & 00070C30 0080007B no-srbs srbs no-alive
|
|
*/
|
|
say ,
|
|
/*cpu number:*/ right(i%4,2,'0')' ',
|
|
/*cpu ver : */ substr(info,5,2)' ',
|
|
/*cpuid: */ substr(info,7,1),
|
|
/*cpu serial:*/ substr(info,8,5)' ',
|
|
/*cpu type: */ substr(info,13,4)' ',
|
|
/*PSA vaddr:*/ c2x(substr(info,24,4))' ',
|
|
/*PSA raddr:*/ c2x(substr(info,28,4))' ',
|
|
/* the status shown next may change while you run*/,
|
|
/*status:*/ jobs srbs alive
|
|
end
|
|
exit 0
|
|
/* ------------------- subroutines ---------------------- */
|
|
count_bits:
|
|
arg bit_string .
|
|
bit_sum = 0
|
|
do bit=1 to length(bit_string)
|
|
if substr(bit_string,bit,1)='1' then bit_sum=bit_sum + 1
|
|
end
|
|
return(bit_sum)
|
|
X2B: /* X2B is a function for hex to binary string conversion*/
|
|
arg arg .
|
|
bitout=''
|
|
do i=1 to length(arg)
|
|
t=substr(arg,i,1)
|
|
bitout=bitout||hex.t
|
|
end
|
|
return bitout
|
|
init: /* constants needed in x2b */
|
|
hex.0='0000'; hex.1='0001'; hex.2='0010'; hex.3='0011';
|
|
hex.4='0100'; hex.5='0101'; hex.6='0110'; hex.7='0111';
|
|
hex.8='1000'; hex.9='1001'; hex.A='1010'; hex.B='1011';
|
|
hex.C='1100'; hex.D='1101'; hex.E='1110'; hex.F='1111';
|
|
return |