#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <sys/prosrfs.h>
#include <sys/cpu.h>
#include <sys/ipl.h>
#include "X.h"
#include "Xmd.h"
#include "compiler.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
static Bool KeepTty = FALSE;
static Bool Protect0 = FALSE;
static Bool pmaxInitialized = FALSE;
#define VT_DEFAULT -2
#define VT_NONE -1
static int VTnum = VT_DEFAULT;
extern void pmax_init_splmap(void);
int pmax_sys_type;
int
PowerMAXOS_sys_type(void)
{
int fd;
procfile_t procfile;
fd = open("/system/processor/0",O_RDONLY);
if (fd<0) {
FatalError("Cannot open '%s'\n", "/system/processor/0");
}
if (read(fd, &procfile, sizeof(procfile)) < 0) {
FatalError("Cannot read '%s'\n", "/system/processor/0");
}
close(fd);
return(procfile.cpu_model);
}
void
pmaxInit(void)
{
char *mach;
if (pmaxInitialized)
return;
pmaxInitialized = TRUE;
pmax_sys_type = PowerMAXOS_sys_type();
switch(pmax_sys_type) {
case MODEL_NH6400:
mach ="PowerMAXION (NH6400)";
break;
case MODEL_NH6408:
mach = "PowerMAXION (NH6408)";
break;
case MODEL_NH6800T:
mach = "TurboHawk";
break;
case MODEL_MPWR:
mach = "PowerStack";
break;
case MODEL_PH610:
mach = "PowerHawk 610";
break;
case MODEL_MPWR2:
mach = "PowerStack II (utah)";
break;
case MODEL_PH620:
mach = "PowerHawk 620";
break;
case MODEL_PH640:
mach = "PowerHawk 640";
break;
case MODEL_MMTX:
mach = "PowerStack II (MTX)";
break;
default:
FatalError("pmaxInit: Unknown/unsupported machine type 0x%x\n",
pmax_sys_type);
}
xf86Msg(X_INFO, "pmaxInit: Machine type: %s\n", mach);
pmax_init_splmap();
pciInit();
}
void
xf86OpenConsole()
{
struct vt_mode VT;
char vtname[10];
MessageType from = X_DEFAULT;
if (serverGeneration == 1)
{
if (geteuid() != 0)
{
FatalError("xf86OpenConsole: Server must be suid root\n");
}
if (Protect0)
{
int fd = -1;
if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0)
{
xf86Msg(X_WARNING,
"xf86OpenConsole: cannot open /dev/zero (%s)\n",
strerror(errno));
}
else
{
if ((int)mmap(0, 0x1000, PROT_NONE,
MAP_FIXED | MAP_SHARED, fd, 0) == -1)
{
xf86Msg(X_WARNING,
"xf86OpenConsole: failed to protect page 0 (%s)\n",
strerror(errno));
}
close(fd);
}
}
pmaxInit();
if (VTnum == VT_DEFAULT) {
int fd;
if ((fd = open("/dev/vt00",O_WRONLY,0)) < 0) {
xf86Msg(X_WARNING,
"xf86OpenConsole: Could not open /dev/vt00 (%s)\n",
strerror(errno));
VTnum = VT_NONE;
}
else {
if (ioctl(fd, VT_OPENQRY, &VTnum) < 0)
{
xf86Msg(X_WARNING,
"xf86OpenConsole: Cannot find a free VT\n");
VTnum = VT_NONE;
}
close(fd);
}
} else {
from = X_CMDLINE;
}
xf86Info.vtno = VTnum;
if (xf86Info.vtno == VT_NONE)
strcpy(vtname, "/dev/null");
else
sprintf(vtname,"/dev/vt%02d",xf86Info.vtno);
xf86Msg(from, "using VT \"%s\"\n\n", vtname);
if (!KeepTty)
{
setpgrp();
}
if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) < 0)
{
FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
vtname, strerror(errno));
}
if (xf86Info.vtno != VT_NONE)
{
(void) chown(vtname, getuid(), getgid());
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
{
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
}
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
{
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
}
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
{
FatalError("xf86OpenConsole: VT_GETMODE failed\n");
}
signal(SIGUSR1, xf86VTRequest);
VT.mode = VT_PROCESS;
VT.relsig = SIGUSR1;
VT.acqsig = SIGUSR1;
if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
{
FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
}
if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
{
FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
}
}
}
else
{
if (xf86Info.vtno != VT_NONE)
{
if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
{
xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
}
if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
{
xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
}
if (!xf86Screens[0]->vtSema)
sleep(5);
}
}
return;
}
void xf86CloseConsole()
{
struct vt_mode VT;
if (xf86Info.vtno != VT_NONE)
{
#if 0
ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno);
ioctl(xf86Info.consoleFd, VT_WAITACTIVE, 0);
#endif
ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT);
if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
{
VT.mode = VT_AUTO;
ioctl(xf86Info.consoleFd, VT_SETMODE, &VT);
}
}
close(xf86Info.consoleFd);
return;
}
int xf86ProcessArgument(argc, argv, i)
int argc;
char *argv[];
int i;
{
if (!strcmp(argv[i], "-keeptty"))
{
KeepTty = TRUE;
return(1);
}
if (!strcmp(argv[i], "-novt"))
{
VTnum = VT_NONE;
return(1);
}
if (!strcmp(argv[i], "-protect0"))
{
Protect0 = TRUE;
return(1);
}
if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
{
if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
{
UseMsg();
VTnum = VT_DEFAULT;
return(0);
}
return(1);
}
return(0);
}
void xf86UseMsg()
{
ErrorF("vtXX use the specified VT number\n");
ErrorF("-keeptty ");
ErrorF("don't detach controlling tty (for debugging only)\n");
ErrorF("-novt ");
ErrorF("don't allocate and open a new virtual terminal\n");
return;
}
void
xf86_pmax_usleep(unsigned long n)
{
struct timespec requested,remaining;
int rv;
requested.tv_sec = n/1000000;
requested.tv_nsec = (n % 1000000) * 1000;
while ((rv = nanosleep(&requested,&remaining)) < 0) {
if (errno != EINTR)
break;
remaining = requested;
}
if (rv) {
ErrorF("xf86_pmax_usleep: nanosleep() failed: rv=%d, errno=%d\n", rv, errno);
}
}
#ifndef usleep
void
usleep(unsigned long n)
{
xf86_pmax_usleep(n);
}
#endif