mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-04-13 15:35:41 +02:00
821 lines
27 KiB
C
821 lines
27 KiB
C
/* LOADPARM.C (c) Copyright Jan Jaeger, 2004-2012 */
|
|
/* (c) Copyright TurboHercules, SAS 2010-2011 */
|
|
/* SCLP / MSSF loadparm */
|
|
/* */
|
|
/* Released under "The Q Public License Version 1" */
|
|
/* (http://www.hercules-390.org/herclic.html) as modifications to */
|
|
/* Hercules. */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* This module contains functions which set, copy, and retrieve the */
|
|
/* values of the LOADPARM and various other environmental parameters */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#include "hstdinc.h"
|
|
|
|
#ifndef _LOADPARM_C_
|
|
#define _LOADPARM_C_
|
|
#endif
|
|
#ifndef _HENGINE_DLL_
|
|
#define _HENGINE_DLL_
|
|
#endif
|
|
|
|
#include "hercules.h"
|
|
|
|
/* H E R C U L E S */
|
|
static const BYTE dflt_lparname[8] = { 0xC8,0xC5,0xD9,0xC3,0xE4,0xD3,0xC5,0xE2 };
|
|
|
|
/* E M U L A T O R */
|
|
static const BYTE dflt_model[16] = { 0xC5,0xD4,0xE4,0xD3,0xC1,0xE3,0xD6,0xD9,
|
|
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
|
|
/* H R C */
|
|
static const BYTE default_manufact[16] = { 0xC8,0xD9,0xC3,0x40,0x40,0x40,0x40,0x40,
|
|
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
|
|
/* Z Z */
|
|
static const BYTE default_plant[4] = { 0xE9,0xE9,0x40,0x40 };
|
|
/* H E R C U L E S */
|
|
static const BYTE dflt_cpid[16] = { 0xC8,0xC5,0xD9,0xC3,0xE4,0xD3,0xC5,0xE2,
|
|
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 };
|
|
/* H E R C U L E S */
|
|
static const BYTE dflt_vmid[8] = { 0xC8,0xC5,0xD9,0xC3,0xE4,0xD3,0xC5,0xE2 };
|
|
|
|
static int gsysinfo_init_flg = FALSE;
|
|
|
|
static GSYSINFO gsysinfo;
|
|
/* defaults
|
|
= { { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }, // loadparm
|
|
{ 0xC8,0xC5,0xD9,0xC3,0xE4,0xD3,0xC5,0xE2 }, // lparname
|
|
{ 0xC8,0xD9,0xC3,0x40,0x40,0x40,0x40,0x40, // manufact
|
|
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 },
|
|
{ 0xE9,0xE9,0x40,0x40 }, // plant
|
|
{ 0xC5,0xD4,0xE4,0xD3,0xC1,0xE3,0xD6,0xD9, // model
|
|
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 },
|
|
{ 0xC5,0xD4,0xE4,0xD3,0xC1,0xE3,0xD6,0xD9, // modelcapa
|
|
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 },
|
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // modelperm
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // modeltemp
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
|
{ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }, // systype
|
|
{ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }, // sysname
|
|
{ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }, // sysplex
|
|
{ 0xC8,0xC5,0xD9,0xC3,0xE4,0xD3,0xC5,0xE2, // cpid
|
|
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 },
|
|
{ 0xC8,0xC5,0xD9,0xC3,0xE4,0xD3,0xC5,0xE2 } // vmid
|
|
};
|
|
*/
|
|
|
|
// ebcdic_to_stringz_allow_return returns a null terminated string allowing
|
|
// embedded spaces
|
|
#define ebcdic_to_stringz_allow_return(_field) \
|
|
{ \
|
|
static char result[sizeof(_field)+1]; \
|
|
int i; \
|
|
result[sizeof(_field)] = 0; \
|
|
for (i = sizeof(_field) - 1; i >= 0 && _field[i] == 0x40; i--) \
|
|
result[i] = 0; \
|
|
for (; i >= 0; i--) \
|
|
result[i] = guest_to_host((int)_field[i]); \
|
|
return result; \
|
|
}
|
|
|
|
|
|
// ebcdic_to_stringz_return returns a null terminated string stopping
|
|
// at first embedded blank or end of field
|
|
|
|
#define ebcdic_to_stringz_return(_field) \
|
|
{ \
|
|
static char result[sizeof(_field)+1]; \
|
|
copy_ebcdic_to_stringz(result, sizeof(result), _field, sizeof(_field)); \
|
|
return result; \
|
|
}
|
|
|
|
|
|
// set_static
|
|
|
|
#define set_static(_target,_source) \
|
|
{ \
|
|
size_t i = 0; \
|
|
size_t n = MIN(strlen(_source), sizeof(_target)); \
|
|
if (_source) \
|
|
{ \
|
|
for (; i < n; i++) \
|
|
if (isprint(_source[i])) \
|
|
_target[i] = host_to_guest((int)toupper(_source[i])); \
|
|
else \
|
|
_target[i] = 0x40; \
|
|
} \
|
|
for (; i < sizeof(_target); i++) \
|
|
_target[i] = 0x40; \
|
|
}
|
|
|
|
|
|
// set_stsi_and_return
|
|
|
|
#define set_stsi_and_return(_target,_source,_default) \
|
|
{ \
|
|
size_t i; \
|
|
int n; \
|
|
BYTE temp[sizeof(_target)]; \
|
|
memset(temp, 0x40, sizeof(temp) ); \
|
|
for (i = 0, n = 0; name && i < strlen(name) && i < sizeof(temp); i++) \
|
|
if (isalnum(name[i])) \
|
|
{ \
|
|
temp[i] = host_to_guest((int)toupper(name[i])); \
|
|
n++; \
|
|
} \
|
|
else \
|
|
return -1; /* 0-9, A-Z */ \
|
|
if ( n > 0 ) /* valid if > 0 count */ \
|
|
memcpy(_target,temp,sizeof(_target)); \
|
|
else \
|
|
memcpy(_target,_default,MIN(sizeof(_target),sizeof(_default))); \
|
|
return n; \
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Subroutine to initialize (when NULL dest is passed) or retrieve */
|
|
/* Guest System Information */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
static void get_gsysinfo(GSYSINFO *dest)
|
|
{
|
|
if ( dest == NULL )
|
|
{
|
|
gsysinfo_init_flg = TRUE;
|
|
memset(&gsysinfo, 0x40, sizeof(GSYSINFO));
|
|
|
|
memcpy(gsysinfo.lparname, dflt_lparname, sizeof(gsysinfo.lparname));
|
|
memcpy(gsysinfo.manufact, default_manufact, sizeof(gsysinfo.manufact));
|
|
memcpy(gsysinfo.plant, default_plant, sizeof(gsysinfo.plant));
|
|
memcpy(gsysinfo.model, dflt_model, sizeof(gsysinfo.model));
|
|
memcpy(gsysinfo.modelcapa, dflt_model, sizeof(gsysinfo.modelcapa));
|
|
memcpy(gsysinfo.cpid, dflt_cpid, sizeof(gsysinfo.cpid));
|
|
memcpy(gsysinfo.vmid, dflt_vmid, sizeof(gsysinfo.vmid));
|
|
|
|
memset(gsysinfo.modelperm, 0, sizeof(gsysinfo.modelperm));
|
|
memset(gsysinfo.modeltemp, 0, sizeof(gsysinfo.modeltemp));
|
|
}
|
|
else
|
|
memcpy( dest, &gsysinfo, sizeof(GSYSINFO) );
|
|
return;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* SUBROUTINE TO COPY A STRINGZ TO A FIXED-LENGTH EBCDIC FIELD */
|
|
/*-------------------------------------------------------------------*/
|
|
static int copy_stringz_to_ebcdic(BYTE* fld, size_t len, char *name)
|
|
{
|
|
size_t i;
|
|
size_t copylen;
|
|
int n;
|
|
BYTE *temp_fld;
|
|
|
|
if ( name == NULL || strlen(name) == 0 )
|
|
{
|
|
memset(fld, 0, len);
|
|
return 0;
|
|
}
|
|
|
|
temp_fld = (BYTE *)malloc(len+1);
|
|
memset(temp_fld, 0x40, len);
|
|
copylen = MIN(strlen(name), len);
|
|
|
|
for ( i = 0, n = 0; i < copylen; i++ )
|
|
if ( isalnum(name[i]) )
|
|
{
|
|
temp_fld[i] = host_to_guest((int)toupper(name[i]));
|
|
n++;
|
|
}
|
|
else
|
|
{
|
|
n = -1;
|
|
break;
|
|
}
|
|
|
|
if ( n > 0 )
|
|
memcpy(fld,temp_fld,len);
|
|
|
|
free(temp_fld);
|
|
|
|
return n;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* SUBROUTINE TO COPY A FIXED-LENGTH EBCDIC FIELD TO A STRINGZ */
|
|
/*-------------------------------------------------------------------*/
|
|
static int copy_ebcdic_to_stringz(char *name, size_t nlen, BYTE* fld, size_t flen)
|
|
{
|
|
size_t i;
|
|
size_t copylen;
|
|
char c;
|
|
|
|
if ( name == NULL || nlen == 0 || flen == 0 ) return -1;
|
|
|
|
memset(name, 0, nlen);
|
|
copylen = MIN(nlen-1, flen);
|
|
|
|
for ( i = 0; i < copylen; i++ )
|
|
{
|
|
c = guest_to_host(fld[i]);
|
|
|
|
if ( c == SPACE || !isalnum(c) )
|
|
break; /* there should not be any embedded blanks */
|
|
|
|
name[i] = c;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
/*-------------------------------------------------------------------*/
|
|
/* LOAD PARAMETER */
|
|
/* Set by: LOADPARM configuration statement or panel command */
|
|
/* Retrieved by: SERVC and MSSF_CALL instructions */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
void set_loadparm(char *name)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
set_static(gsysinfo.loadparm, name);
|
|
}
|
|
|
|
|
|
void get_loadparm(BYTE *dest)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dest, gsysinfo.loadparm, sizeof(gsysinfo.loadparm));
|
|
}
|
|
|
|
|
|
char *str_loadparm()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_allow_return(gsysinfo.loadparm);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* LOGICAL PARTITION NAME */
|
|
/* Set by: LPARNAME configuration statement */
|
|
/* Retrieved by: STSI and MSSF_CALL instructions */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
void set_lparname(char *name)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
set_static(gsysinfo.lparname, name);
|
|
}
|
|
|
|
|
|
void get_lparname(BYTE *dest)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dest, gsysinfo.lparname, sizeof(gsysinfo.lparname));
|
|
}
|
|
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char *str_lparname()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.lparname);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* MANUFACTURER NAME */
|
|
/* Set by: MANUFACTURER configuration statement */
|
|
/* Retrieved by: STSI instruction */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
int set_manufacturer(char *name)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
set_stsi_and_return(gsysinfo.manufact, name, default_manufact);
|
|
}
|
|
|
|
|
|
void get_manufacturer(BYTE *dest)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dest, gsysinfo.manufact, sizeof(gsysinfo.manufact));
|
|
}
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char *str_manufacturer()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.manufact);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* MANUFACTURING PLANT NAME */
|
|
/* Set by: PLANT configuration statement */
|
|
/* Retrieved by: STSI instruction A-Z, 0-9 */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
int set_plant(char *name)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
set_stsi_and_return(gsysinfo.plant, name, default_plant);
|
|
}
|
|
|
|
void get_plant(BYTE *dest)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dest, gsysinfo.plant, sizeof(gsysinfo.plant));
|
|
}
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char *str_plant()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.plant);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* MODEL IDENTIFICATION */
|
|
/* Set by: MODEL configuration statement */
|
|
/* Retrieved by: STSI instruction */
|
|
/* Notes: Although model and modelcapa are initially set to EBCDIC
|
|
* "EMULATOR" it is possible for model, modeltemp, modelperm each to
|
|
* be binary zero filled fields. "modelcapa" may never be binary zero.
|
|
* All blanks is invalid for any of the fields. An attempt to set any
|
|
* field other than "modelcapa" to all blanks will result in the field
|
|
* being set to binary zeros. "modelcapa" must have at least one
|
|
* character in the field. Valid characters are 0-9,A-Z, right padded
|
|
* with blanks. '*' means not specified (keep existing value/default),
|
|
* '=' means use same value that was specified in the previous field,
|
|
* empty string means field is undefined (set field to binary zeros).
|
|
*/
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
int set_model(char *m1, char *m2, char *m3, char *m4)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
/* Model may be binary zero */
|
|
if ( m1 != NULL && m1[0] != '*' )
|
|
{
|
|
if ( strlen(m1) == 0 )
|
|
memset(gsysinfo.model, 0, sizeof(gsysinfo.model));
|
|
else if ( strcmp(m1, "=") == 0)
|
|
memcpy(gsysinfo.model, dflt_model, sizeof(gsysinfo.model));
|
|
else if ( copy_stringz_to_ebcdic(gsysinfo.model, sizeof(gsysinfo.model), m1) <= 0 ) return 1;
|
|
}
|
|
else if ( m1 == NULL )
|
|
return 0;
|
|
|
|
/* model-capa may NEVER be binary zero, if "" then default to
|
|
the same value as the Model field if not binary zero. Otherwise
|
|
if the Model field is binary zero the value 'EMULATOR' is used */
|
|
if ( m2 != NULL && m2[0] != '*' )
|
|
{
|
|
if ( strlen(m2) == 0 || strcmp(m2, "=") == 0)
|
|
memcpy(gsysinfo.modelcapa, gsysinfo.model[0] ? gsysinfo.model : dflt_model, sizeof(gsysinfo.modelcapa));
|
|
else if ( copy_stringz_to_ebcdic(gsysinfo.modelcapa, sizeof(gsysinfo.modelcapa), m2) <= 0) return 2;
|
|
}
|
|
else if ( m2 == NULL )
|
|
return 0;
|
|
|
|
/* model-perm may be binary zero */
|
|
if ( m3 != NULL && m3[0] != '*' )
|
|
{
|
|
if ( strlen(m3) == 0 )
|
|
memset(gsysinfo.modelperm, 0, sizeof(gsysinfo.modelperm));
|
|
else if ( strcmp(m3, "=") == 0)
|
|
memcpy(gsysinfo.modelperm, gsysinfo.modelcapa, sizeof(gsysinfo.modelperm));
|
|
else if ( copy_stringz_to_ebcdic(gsysinfo.modelperm, sizeof(gsysinfo.modelperm), m3) <= 0 ) return 3;
|
|
}
|
|
else if ( m3 == NULL )
|
|
return 0;
|
|
|
|
/* model-temp may be binary zero */
|
|
if ( m4 != NULL && m4[0] != '*' )
|
|
{
|
|
if ( strlen(m4) == 0 )
|
|
memset(gsysinfo.modeltemp, 0, sizeof(gsysinfo.modeltemp));
|
|
else if ( strcmp(m4, "=") == 0)
|
|
memcpy(gsysinfo.modeltemp, gsysinfo.modelperm, sizeof(gsysinfo.modeltemp));
|
|
else if ( copy_stringz_to_ebcdic(gsysinfo.modeltemp, sizeof(gsysinfo.modeltemp), m4) <= 0 ) return 4;
|
|
}
|
|
// else if ( m4 == NULL ) // uncomment test if anything else is done
|
|
// return 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char **str_model()
|
|
{
|
|
static char h_model[sizeof(gsysinfo.model)+1];
|
|
static char c_model[sizeof(gsysinfo.modelcapa)+1];
|
|
static char p_model[sizeof(gsysinfo.modelperm)+1];
|
|
static char t_model[sizeof(gsysinfo.modeltemp)+1];
|
|
static char *models[5] = { h_model, c_model, p_model, t_model, NULL };
|
|
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memset(h_model, 0, sizeof(h_model));
|
|
memset(c_model, 0, sizeof(c_model));
|
|
memset(p_model, 0, sizeof(p_model));
|
|
memset(t_model, 0, sizeof(t_model));
|
|
|
|
(void)copy_ebcdic_to_stringz(h_model, sizeof(h_model), gsysinfo.model, sizeof(gsysinfo.model));
|
|
(void)copy_ebcdic_to_stringz(c_model, sizeof(c_model), gsysinfo.modelcapa, sizeof(gsysinfo.modelcapa));
|
|
(void)copy_ebcdic_to_stringz(p_model, sizeof(p_model), gsysinfo.modelperm, sizeof(gsysinfo.modelperm));
|
|
(void)copy_ebcdic_to_stringz(t_model, sizeof(t_model), gsysinfo.modeltemp, sizeof(gsysinfo.modeltemp));
|
|
|
|
return models;
|
|
}
|
|
|
|
void get_model(BYTE *dest)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dest, gsysinfo.model, sizeof(gsysinfo.model));
|
|
}
|
|
|
|
void get_modelcapa(BYTE *dest)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dest, gsysinfo.modelcapa, sizeof(gsysinfo.modelcapa));
|
|
}
|
|
|
|
void get_modelperm(BYTE *dest)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dest, gsysinfo.modelperm, sizeof(gsysinfo.modelperm));
|
|
}
|
|
|
|
void get_modeltemp(BYTE *dest)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dest, gsysinfo.modeltemp, sizeof(gsysinfo.modeltemp));
|
|
}
|
|
|
|
char *str_modelhard()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.model);
|
|
}
|
|
|
|
char *str_modelcapa()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.modelcapa);
|
|
}
|
|
|
|
char *str_modelperm()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.modelperm);
|
|
}
|
|
|
|
char *str_modeltemp()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.modeltemp);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* SYSTEM TYPE IDENTIFICATION */
|
|
/* Set by: SERVC instruction */
|
|
/* Retrieved by: DIAG204 instruction */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
void set_systype(BYTE *src)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(gsysinfo.systype, src, sizeof(gsysinfo.systype));
|
|
}
|
|
|
|
void get_systype(BYTE *dst)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dst, gsysinfo.systype, sizeof(gsysinfo.systype));
|
|
}
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char *str_systype()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.systype);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* SYSTEM NAME */
|
|
/* Set by: SERVC instruction */
|
|
/* Retrieved by: DIAG204 instruction */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
void set_sysname(BYTE *src)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(gsysinfo.sysname, src, sizeof(gsysinfo.sysname));
|
|
}
|
|
|
|
void get_sysname(BYTE *dst)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dst, gsysinfo.sysname, sizeof(gsysinfo.sysname));
|
|
}
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char *str_sysname()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.sysname);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* SYSPLEX NAME */
|
|
/* Set by: SERVC instruction */
|
|
/* Retrieved by: DIAG204 instruction */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
void set_sysplex(BYTE *src)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(gsysinfo.sysplex, src, sizeof(gsysinfo.sysplex));
|
|
}
|
|
|
|
void get_sysplex(BYTE *dst)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dst, gsysinfo.sysplex, sizeof(gsysinfo.sysplex));
|
|
}
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char *str_sysplex()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.sysplex);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* VIRTUAL MACHINE ID */
|
|
/* Set by: VMD configuration statement */
|
|
/* Retrieved by: STSI instruction */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
void set_vmid(BYTE *src)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(gsysinfo.vmid, src, sizeof(gsysinfo.vmid));
|
|
}
|
|
|
|
void get_vmid(BYTE *dst)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dst, gsysinfo.vmid, sizeof(gsysinfo.vmid));
|
|
}
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char *str_vmid()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.vmid);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* CONTROL PROGRAM ID */
|
|
/* Set by: VMD configuration statement */
|
|
/* Retrieved by: STSI instruction */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
void set_cpid(BYTE *src)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(gsysinfo.cpid, src, sizeof(gsysinfo.cpid));
|
|
}
|
|
|
|
void get_cpid(BYTE *dst)
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
memcpy(dst, gsysinfo.cpid, sizeof(gsysinfo.cpid));
|
|
}
|
|
|
|
LOADPARM_DLL_IMPORT
|
|
char *str_cpid()
|
|
{
|
|
if (gsysinfo_init_flg == FALSE )
|
|
get_gsysinfo(NULL);
|
|
|
|
ebcdic_to_stringz_return(gsysinfo.cpid);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Retrieve Multiprocessing CPU-Capability Adjustment Factors */
|
|
/* */
|
|
/* This function retrieves the Multiprocessing CPU-Capability */
|
|
/* Adjustment Factor values for SYSIB (System Information Block) */
|
|
/* 1.2.2 as described in the Principles of Operations manual for */
|
|
/* the STORE SYSTEM INFORMATION instruction. */
|
|
/* */
|
|
/* Input: */
|
|
/* dest Address of where to store the information. */
|
|
/* Output: */
|
|
/* The requested MP Factor values at the address specified. */
|
|
/* Used by: */
|
|
/* B27D STSI Store System Information (Basic-machine All CPUs) */
|
|
/* B220 SERVC Service Call (read_scpinfo) */
|
|
/*-------------------------------------------------------------------*/
|
|
void get_mpfactors(BYTE *dest)
|
|
{
|
|
/*-------------------------------------------------------------------*/
|
|
/* The new z10 machine will use a denominator of 65535 for better */
|
|
/* granularity. But this will mess up old software. We will stick */
|
|
/* to the old value of 100. Bernard Feb 26, 2010. */
|
|
/* */
|
|
/* Calculations will be done in a higher precision to prevent early */
|
|
/* truncation and degradation of the factors. To achieve this, the */
|
|
/* factors are calculated * 256. When storing the values, the */
|
|
/* individual values are rounded up by 128 and then divided by 256 */
|
|
/* for the store operation. */
|
|
/* */
|
|
/* Once the number of host logical CPUs is reached, subsequent MP */
|
|
/* factors are no longer adjusted. */
|
|
/* */
|
|
/* MPFACTOR_DENOMINATOR must be 100, 255, or 65535. */
|
|
/* */
|
|
/* It is recommended that MPFACTOR_PERCENT remain at 95 (95%). */
|
|
/*-------------------------------------------------------------------*/
|
|
#define MPFACTOR_DENOMINATOR 100
|
|
#define MPFACTOR_PERCENT 95
|
|
|
|
static U16 mpfactors[MAX_CPU_ENGINES-1] = {0};
|
|
static BYTE didthis = 0;
|
|
|
|
if (!didthis)
|
|
{
|
|
/* First time: initialize array... */
|
|
size_t limit = get_RealCPCount();
|
|
size_t i;
|
|
U32 mpfactor = MPFACTOR_DENOMINATOR << 8;
|
|
U16 result = 0;
|
|
U16 resmin = 1;
|
|
|
|
switch (MPFACTOR_DENOMINATOR)
|
|
{
|
|
default: /* resmin = 1; break; */
|
|
case 100: resmin = 1; break;
|
|
case 255: resmin = 101; break;
|
|
case 65535: resmin = 256; break;
|
|
}
|
|
|
|
for (i=0; i < arraysize(mpfactors); i++)
|
|
{
|
|
/* Calculate the value of each subsequent entry as a
|
|
* percentage of the previous entry's value for the real
|
|
* defined CPU entries.
|
|
*/
|
|
if (i < limit)
|
|
{
|
|
mpfactor = (mpfactor * MPFACTOR_PERCENT) / 100;
|
|
result = (mpfactor + 128) >> 8;
|
|
result = MAX(result, resmin);
|
|
}
|
|
STORE_HW( &mpfactors[i], result );
|
|
}
|
|
didthis = 1;
|
|
}
|
|
|
|
/* Return the requested information... */
|
|
memcpy( dest, &mpfactors[0], (MAX_CPU_ENGINES-1) * sizeof(U16) );
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* get_RealCPCount - Get the maximum count of possible concurrently */
|
|
/* dispatchable CP engines on the host processor. */
|
|
/*-------------------------------------------------------------------*/
|
|
unsigned int
|
|
get_RealCPCount (void)
|
|
{
|
|
unsigned int possible;
|
|
unsigned int reserved;
|
|
unsigned int cp = 0;
|
|
unsigned int cpu;
|
|
unsigned int result;
|
|
|
|
/* Initialize the number of possible concurrently dispatchable CP
|
|
* engines, taking into account that any of the hostinfo fields
|
|
* may be zero when not reported by the host OS.
|
|
*/
|
|
if (hostinfo.num_logical_cpu)
|
|
possible = hostinfo.num_logical_cpu;
|
|
else if (hostinfo.num_procs)
|
|
{
|
|
if (hostinfo.num_physical_cpu)
|
|
possible = hostinfo.num_procs * hostinfo.num_physical_cpu;
|
|
else
|
|
possible = hostinfo.num_procs;
|
|
}
|
|
else
|
|
possible = MAX_CPU_ENGINES;
|
|
|
|
/* Limit to the maximum number of Hercules CPU engines */
|
|
if (possible > MAX_CPU_ENGINES)
|
|
possible = MAX_CPU_ENGINES;
|
|
|
|
/* Set number of reserved processors */
|
|
reserved = possible - sysblk.cpus;
|
|
|
|
/* Count the number of defined CP processors */
|
|
for ( cpu = 0; cpu < (unsigned) sysblk.hicpu; ++cpu )
|
|
{
|
|
/* Loop through online CP CPUs */
|
|
if ( IS_CPU_ONLINE(cpu) )
|
|
{
|
|
if ( sysblk.ptyp[cpu] == SCCB_PTYP_CP )
|
|
++cp;
|
|
}
|
|
}
|
|
|
|
/* The result is the number of CP processors plus the number of
|
|
* reserved processors that may become CP processors, limited by the
|
|
* number of possible physical/logical processors.
|
|
*/
|
|
result = MIN(cp + reserved, possible);
|
|
|
|
return (result);
|
|
}
|