1
0
Files
irix-657m-src/stand/arcs/lib/libsk/ml/nvcompat.c
2022-09-29 17:59:04 +03:00

259 lines
7.0 KiB
C

#ident "lib/libsk/ml/nvcompat.c: $Revision: 1.23 $"
/*
* nvcompat.c -- nvram compatitility functions
*/
#include <sys/types.h>
#include <sys/sbd.h>
#include <sys/cpu.h>
#include <stringlist.h>
#include <libsc.h>
#include <ctype.h>
#include <net/in.h>
#include <libsk.h>
#if DEBUG
extern int Debug;
#endif
#if defined(IP20)
/* Defines from the old IP12nvram.h file. These specify the old layout
* of the nvram needed for IP12 -> IP20 upgrade.
*/
#define OLD_NVLEN_MAX 128
#define OLD_NVOFF_BOOTMODE 0
#define OLD_NVLEN_BOOTMODE 1
#define OLD_NVOFF_NETADDR 2
#define OLD_NVLEN_NETADDR 16
#define OLD_NVOFF_LBAUD (OLD_NVOFF_NETADDR + OLD_NVLEN_NETADDR)
#define OLD_NVLEN_LBAUD 5
#define OLD_NVOFF_RBAUD (OLD_NVOFF_LBAUD + OLD_NVLEN_LBAUD)
#define OLD_NVLEN_RBAUD 5
#define OLD_NVOFF_CONSOLE (OLD_NVOFF_RBAUD + OLD_NVLEN_RBAUD)
#define OLD_NVLEN_CONSOLE 1
#define OLD_NVOFF_SCCOLOR (OLD_NVOFF_CONSOLE + OLD_NVLEN_CONSOLE)
#define OLD_NVLEN_SCCOLOR 6
#define OLD_NVOFF_PGCOLOR (OLD_NVOFF_SCCOLOR + OLD_NVLEN_SCCOLOR)
#define OLD_NVLEN_PGCOLOR 6
#define OLD_NVOFF_LGCOLOR (OLD_NVOFF_PGCOLOR + OLD_NVLEN_PGCOLOR)
#define OLD_NVLEN_LGCOLOR 6
#define OLD_NVOFF_PAD0 (OLD_NVOFF_LGCOLOR + OLD_NVLEN_LGCOLOR)
#define OLD_NVLEN_PAD0 2
#define OLD_NVOFF_CHECKSUM (OLD_NVOFF_PAD0 + OLD_NVLEN_PAD0)
#define OLD_NVLEN_CHECKSUM 1
#define OLD_NVOFF_DISKLESS (OLD_NVOFF_CHECKSUM + OLD_NVLEN_CHECKSUM)
#define OLD_NVLEN_DISKLESS 1
#define OLD_NVOFF_NOKBD (OLD_NVOFF_DISKLESS + OLD_NVLEN_DISKLESS)
#define OLD_NVLEN_NOKBD 1
#define OLD_NVOFF_BOOTFILE (OLD_NVOFF_NOKBD + OLD_NVLEN_NOKBD)
#define OLD_NVLEN_BOOTFILE 50
#define OLD_NVOFF_PASSWD_KEY (OLD_NVOFF_BOOTFILE+OLD_NVLEN_BOOTFILE)
#define OLD_NVLEN_PASSWD_KEY 17
#define OLD_NVOFF_VOLUME (OLD_NVOFF_PASSWD_KEY+OLD_NVLEN_PASSWD_KEY)
#define OLD_NVLEN_VOLUME 3
#define OLD_NVLEN_ENET 6
#define OLD_NVOFF_ENET (OLD_NVLEN_MAX-OLD_NVLEN_ENET)
/*
* oldnvchecksum -- calculate new checksum for non-volatile RAM
*/
static char
oldnvchecksum(void)
{
register int nv_reg;
unsigned short nv_val;
/*
* Seed the checksum so all-zeroes (all-ones) nvram doesn't have a zero
* (all-ones) checksum.
*/
register signed char checksum = 0xa5;
/*
* do the checksum on all of the nvram, skip the checksum byte !!
*/
for (nv_reg = 0; nv_reg < OLD_NVLEN_MAX / 2; nv_reg++)
{
cpu_get_nvram_buf(nv_reg << 1, 2, (char *)&nv_val);
if (nv_reg == (OLD_NVOFF_CHECKSUM / 2))
if (OLD_NVOFF_CHECKSUM & 0x01)
checksum ^= nv_val >> 8;
else
checksum ^= nv_val & 0xff;
else
checksum ^= (nv_val >> 8) ^ (nv_val & 0xff);
/* following is a tricky way to rotate */
checksum = (checksum << 1) | (checksum < 0);
}
return (char)checksum;
}
int
cpu_is_oldnvram(void)
{
/* try twice */
if (oldnvchecksum() !=
*cpu_get_nvram_offset(OLD_NVOFF_CHECKSUM,OLD_NVLEN_CHECKSUM) &&
oldnvchecksum() !=
*cpu_get_nvram_offset(OLD_NVOFF_CHECKSUM,OLD_NVLEN_CHECKSUM) )
return 0;
return 1;
}
/* These are the old nvram entries we wish to copy to the new
* nvram locations.
*/
static struct onvram_entry {
char *nt_name;
int nt_nvaddr;
int nt_nvlen;
} old_table[] = {
{ "netaddr", OLD_NVOFF_NETADDR, OLD_NVLEN_NETADDR },
{ "dbaud", OLD_NVOFF_LBAUD, OLD_NVLEN_LBAUD },
{ "rbaud", OLD_NVOFF_RBAUD, OLD_NVLEN_RBAUD },
{ "diskless", OLD_NVOFF_DISKLESS, OLD_NVLEN_DISKLESS },
{ "pagecolor", OLD_NVOFF_PGCOLOR, OLD_NVLEN_PGCOLOR },
{ "nogfxkbd", OLD_NVOFF_NOKBD, OLD_NVLEN_NOKBD },
{ "passwd_key", OLD_NVOFF_PASSWD_KEY,OLD_NVLEN_PASSWD_KEY },
{ "volume", OLD_NVOFF_VOLUME, OLD_NVLEN_VOLUME },
{ "bootmode", OLD_NVOFF_BOOTMODE, OLD_NVLEN_BOOTMODE },
{ "console", OLD_NVOFF_CONSOLE, OLD_NVLEN_CONSOLE },
{ 0,0,0 }
};
/* These are the new nvram entries that are not updated from the
* old nvram.
*/
static char *not_updated[] = {
"OSLoader",
"OSLoadFilename",
"OSLoadOptions",
"SystemPartition",
"OSLoadPartition",
"TimeZone",
"FWSearchPath",
"scsiretries",
"scsihostid",
"netpasswd_key",
"keybd",
"lang",
"sgilogo",
"nogui",
0
};
/* see comment in nvram.c */
#if _NT_PROM
extern int little_endian;
#define default(entry) \
((little_endian && alt_defaults[(entry)-env_table]) ? \
alt_defaults[(entry)-env_table] : (entry)->nt_value)
extern char *alt_defaults[];
#else
#define default(entry) (entry)->nt_value
#endif
extern struct nvram_entry env_table[];
void
cpu_update_nvram(void)
{
struct onvram_entry *old;
struct nvram_entry *new;
char oldnv[128], string[64], **cp;
/* Get a copy of the entire old nvram image
*/
cpu_get_nvram_buf(0, OLD_NVLEN_MAX, oldnv);
/* Clear out the old checksum
*/
string[0] = 0;
cpu_set_nvram_offset(OLD_NVOFF_CHECKSUM, OLD_NVLEN_CHECKSUM, string);
cpu_nv_lock(0); /* unlock the nvram */
/* copy the ethernet address to its new location
*/
bcopy (oldnv+OLD_NVOFF_ENET, string, OLD_NVLEN_ENET);
string[OLD_NVLEN_ENET] = '\0';
syssetenv ("eaddr", htoe((unsigned char *)string));
cpu_nv_lock(1); /* relock the nvram at the new location */
/* Copy the old nvram information to the new locations.
*/
for (old = old_table; old->nt_nvlen; old++) {
if (!strcmp (old->nt_name, "bootmode")) {
*string = *((char *)oldnv+old->nt_nvaddr);
/* set AutoLoad, and diagmode based on old bootmode */
syssetenv("AutoLoad", *string == 'c' ? "Yes" : "No");
syssetenv("diagmode", *string == 'd' ? "v" : "");
continue;
}
/* The rest of the entries are the same size and meaning
*
* Find the corresponding new entry
*/
for (new = env_table; new->nt_nvlen; new++)
if (!strcmp(new->nt_name, old->nt_name))
break;
if (new->nt_nvlen) {
bcopy (oldnv+old->nt_nvaddr, string, old->nt_nvlen);
string[old->nt_nvlen] = '\0';
syssetenv (new->nt_name, string);
}
}
/* Now fixup the remainder of the nvram that had no corresponding
* entries in the old nvram.
*/
for (cp = not_updated; *cp; ++cp) {
/* Find the corresponding new entry */
for (new = env_table; new->nt_nvlen; new++)
if (!strcmp(new->nt_name, *cp))
break;
if (new->nt_nvlen)
syssetenv (*cp, default(new));
}
}
#elif IP26 || IP28 /* Handle IP22 -> IP26/28 upgrade */
int
cpu_is_oldnvram(void)
{
char nvchecksum(void);
/* If do not have a revision 8 (old) layout, the layout is scrambled.
*/
if (*cpu_get_nvram_offset(NVOFF_REVISION,NVLEN_REVISION) != 8)
return 0;
/* Given a revision 8 layout, if checksum is ok, we have a IP22 ->
* teton/IP28 upgrade, so return true.
*/
return nvchecksum() ==
*cpu_get_nvram_offset(NVOFF_CHECKSUM,NVLEN_CHECKSUM);
}
void
cpu_update_nvram(void)
{
void initialize_envstrs(void);
/* Update all variables that changed from the real rev 8 to the
* non-rolled rev 8, and in the rev 9.
*/
cpu_set_nvram_offset(NVOFF_MONITOR,NVLEN_MONITOR,"");
cpu_set_nvram_offset(NVOFF_REBOUND,NVLEN_REBOUND,REBOUND_DEFAULT);
cpu_set_nvram_offset(NVOFF_BOOTTUNE,NVLEN_BOOTTUNE,"1");
cpu_set_nvvalid(NULL,NULL);
initialize_envstrs();
}
#endif /* IP20/IP26/IP28 */