[BACK]Return to boot.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / boot / boot

File: [local] / sys / arch / vax / boot / boot / boot.c (download)

Revision 1.1, Tue Mar 4 16:08:35 2008 UTC (16 years, 3 months ago) by nbrk
Branch point for: MAIN

Initial revision

/*	$OpenBSD: boot.c,v 1.16 2006/08/30 20:02:13 miod Exp $ */
/*	$NetBSD: boot.c,v 1.18 2002/05/31 15:58:26 ragge Exp $ */
/*-
 * Copyright (c) 1982, 1986 The Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)boot.c	7.15 (Berkeley) 5/4/91
 */

#include <sys/param.h>
#include <sys/reboot.h>
#include "lib/libsa/stand.h"
#ifdef notyet
#include "lib/libsa/loadfile.h"
#include "lib/libkern/libkern.h"
#endif

#define V750UCODE(x)    ((x>>8)&255)

#include "machine/rpb.h"
#include "machine/sid.h"

#include "vaxstand.h"

/*
 * Boot program... arguments passed in r10 and r11 determine
 * whether boot stops to ask for system name and which device
 * boot comes from.
 */

char line[100];
int	bootdev, debug;
extern	unsigned opendev;

void	usage(char *), boot(char *), halt(char *);
void	Xmain(void);
void	autoconf(void);
int	getsecs(void);
int	setjmp(int *);
int	testkey(void);
#if 0
void	loadpcs(void);
#endif

const struct vals {
	char	*namn;
	void	(*func)(char *);
	char	*info;
} val[] = {
	{"?", usage, "Show this help menu"},
	{"help", usage, "Same as '?'"},
	{"boot", boot, "Load and execute file"},
	{"halt", halt, "Halts the system"},
	{0, 0},
};

int jbuf[10];
int sluttid, senast, skip, askname;
struct rpb bootrpb;

void
Xmain(void)
{
	int io;
	int j, nu;
	char transition = '\010';
#ifdef noyet
	u_long marks[MARK_MAX];
#endif

	io = 0;
	skip = 1;
	autoconf();

	/*
	 * Some VAXstation 4000 PROMs slowly erase the whole screen with \010
	 * if running with glass console - at least VS4000/60 and VS4000/VLC;
	 * this is probably the LCG PROM at fault. Use a different transition
	 * pattern, it's not as nice but it does not take 3(!) seconds to
	 * display...
	 */
	if (((vax_boardtype == VAX_BTYP_46 &&
	      (vax_siedata & 0xff) == VAX_VTYP_46) ||
	     (vax_boardtype == VAX_BTYP_48 &&
	      ((vax_siedata >> 8) & 0xff) == VAX_STYP_48)) &&
	    (vax_confdata & 0x100) == 0)
		transition = ' ';

	askname = bootrpb.rpb_bootr5 & RB_ASKNAME;
	printf("\n\r>> OpenBSD/vax boot [%s] [%s] <<\n", "1.12", __DATE__);
	printf(">> Press enter to autoboot now, or any other key to abort:  ");
	sluttid = getsecs() + 5;
	senast = 0;
	skip = 0;
	setjmp(jbuf);
	for (;;) {
		nu = sluttid - getsecs();
		if (senast != nu)
			printf("%c%d", transition, nu);
		if (nu <= 0)
			break;
		senast = nu;
		if ((j = (testkey() & 0177))) {
			skip = 1;
			if (j != 10 && j != 13) {
				printf("\nPress '?' for help");
				askname = 1;
			}
			break;
		}
	}
	skip = 1;
	printf("\n");

	if (setjmp(jbuf))
		askname = 1;

	/* First try to autoboot */
	if (askname == 0) {
#ifdef notyet
		int err;
#endif
		errno = 0;
		printf("> boot bsd\n");
		exec("bsd", 0, 0);
#ifdef notyet
		marks[MARK_START] = 0;
		err = loadfile("bsd", marks,
		    LOAD_KERNEL|COUNT_KERNEL);
		if (err == 0) {
			machdep_start((char *)marks[MARK_ENTRY],
					      marks[MARK_NSYM],
				      (void *)marks[MARK_START],
				      (void *)marks[MARK_SYM],
				      (void *)marks[MARK_END]);
		}
#endif
		printf("bsd: boot failed: %s\n", strerror(errno));
	}

	/* If any key pressed, or autoboot failed, go to conversational boot */
	for (;;) {
		const struct vals *v = &val[0];
		char *c, *d;

		printf("> ");
		gets(line);

		c = line;
		while (*c == ' ')
			c++;

		if (c[0] == 0)
			continue;

		if ((d = strchr(c, ' ')))
			*d++ = 0;

		while (v->namn) {
			if (strcmp(v->namn, c) == 0)
				break;
			v++;
		}
		if (v->namn)
			(*v->func)(d);
		else
			printf("Unknown command: %s\n", c);
	}
}

void
halt(char *hej)
{
	asm("halt");
}

void
boot(char *arg)
{
	char *fn = "bsd";
	int howto, fl, err;
#ifdef notyet
	u_long marks[MARK_MAX];
#endif

	if (arg) {
		while (*arg == ' ')
			arg++;

		if (*arg != '-') {
			fn = arg;
			if ((arg = strchr(arg, ' '))) {
				*arg++ = 0;
				while (*arg == ' ')
					arg++;
			} else
				goto load;
		}
		if (*arg != '-') {
fail:			printf("usage: boot [filename] [-acsd]\n");
			return;
		}

		howto = 0;

		while (*++arg) {
			if (*arg == 'a')
				howto |= RB_ASKNAME;
			else if (*arg == 'c')
				howto |= RB_CONFIG;
			else if (*arg == 'd')
				howto |= RB_KDB;
			else if (*arg == 's')
				howto |= RB_SINGLE;
			else
				goto fail;
		}
		bootrpb.rpb_bootr5 = howto;
	}
load:  
	exec(fn, 0, 0);
#ifdef notyet
	marks[MARK_START] = 0;
	err = loadfile(fn, marks, LOAD_KERNEL|COUNT_KERNEL);
	if (err == 0) {
		machdep_start((char *)marks[MARK_ENTRY],
				       marks[MARK_NSYM],
			      (void *)marks[MARK_START],
				(void *)marks[MARK_SYM],
				(void *)marks[MARK_END]);
	}
#endif
	printf("Boot failed: %s\n", strerror(errno));
}

#if 0

/* 750 Patchable Control Store magic */

#include "../include/mtpr.h"
#include "../include/cpu.h"
#include "../include/sid.h"
#define	PCS_BITCNT	0x2000		/* number of patchbits */
#define	PCS_MICRONUM	0x400		/* number of ucode locs */
#define	PCS_PATCHADDR	0xf00000	/* start addr of patchbits */
#define	PCS_PCSADDR	(PCS_PATCHADDR+0x8000)	/* start addr of pcs */
#define	PCS_PATCHBIT	(PCS_PATCHADDR+0xc000)	/* patchbits enable reg */
#define	PCS_ENABLE	0xfff00000	/* enable bits for pcs */

#define	extzv(one, two, three,four)	\
({			\
	asm __volatile (" extzv %0,%3,(%1),(%2)+"	\
			:			\
			: "g"(one),"g"(two),"g"(three),"g"(four));	\
})


void
loadpcs(void)
{
	static int pcsdone = 0;
	int mid = mfpr(PR_SID);
	int i, j, *ip, *jp;
	char pcs[100];
	char *cp;

	if ((mid >> 24) != VAX_750 || ((mid >> 8) & 255) < 95 || pcsdone)
		return;
	printf("Updating 11/750 microcode: ");
	for (cp = line; *cp; cp++)
		if (*cp == ')' || *cp == ':')
			break;
	if (*cp) {
		bcopy(line, pcs, 99);
		pcs[99] = 0;
		i = cp - line + 1;
	} else
		i = 0;
	strncpy(pcs + i, "pcs750.bin", sizeof(pcs) - i - 1);
	pcs[sizeof(pcs)-1] = '\0';
	i = open(pcs, 0);
	if (i < 0) {
		printf("bad luck - missing pcs750.bin :-(\n");
		return;
	}
	/*
	 * We ask for more than we need to be sure we get only what we expect.
	 * After read:
	 *	locs 0 - 1023	packed patchbits
	 *	 1024 - 11264	packed microcode
	 */
	if (read(i, (char *)0, 23*512) != 22*512) {
		printf("Error reading %s\n", pcs);
		close(i);
		return;
	}
	close(i);

	/*
	 * Enable patchbit loading and load the bits one at a time.
	 */
	*((int *)PCS_PATCHBIT) = 1;
	ip = (int *)PCS_PATCHADDR;
	jp = (int *)0;
	for (i=0; i < PCS_BITCNT; i++) {
		extzv(i,jp,ip,1);
	}
	*((int *)PCS_PATCHBIT) = 0;

	/*
	 * Load PCS microcode 20 bits at a time.
	 */
	ip = (int *)PCS_PCSADDR;
	jp = (int *)1024;
	for (i=j=0; j < PCS_MICRONUM * 4; i+=20, j++) {
		extzv(i,jp,ip,20);
	}

	/*
	 * Enable PCS.
	 */
	i = *jp;		/* get 1st 20 bits of microcode again */
	i &= 0xfffff;
	i |= PCS_ENABLE;	/* reload these bits with PCS enable set */
	*((int *)PCS_PCSADDR) = i;

	mid = mfpr(PR_SID);
	printf("new rev level=%d\n", V750UCODE(mid));
	pcsdone = 1;
}

#endif

void
usage(char *hej)
{
	const struct vals *v = &val[0];
	int i;

	printf("Commands:\n");
	while (v->namn) {
		printf("%s ", v->namn);
		for (i = 1 + strlen(v->namn); (i & 7) != 0; i++)
			printf(" ");
		printf("%s\n", v->info);
		v++;
	}
}