Пример #1
0
void
main(void)
{
    int i;

    /*
     * We want netopen() to ask for IP address, etc, rather
     * that using bootparams.
     */
    netio_ask = 1;

    printf("\n");
    printf(">> %s, Revision %s (from NetBSD %s)\n",
           bootprog_name, bootprog_rev, bootprog_kernrev);
    printf(">> HP 9000/%s SPU\n", getmachineid());
    gethelp();

    for (;;) {
        printf("sys_inst> ");
        memset(line, 0, sizeof(line));
        kgets(line, sizeof(line));
        if (line[0] == '\n' || line[0] == '\0')
            continue;

        for (i = 0; i < NCMDS; ++i)
            if (strcmp(line, inst_commands[i].ic_cmd) == 0) {
                (*inst_commands[i].ic_func)();
                break;
            }


        if (i == NCMDS)
            printf("unknown command: %s\n", line);
    }
}
Пример #2
0
/*
 * Boot the kernel from the miniroot image into single-user.
 */
void
bootmini(void)
{
    char diskname[64], bootname[64];
    int i;

getdiskname:
    printf("Disk to boot from? ");
    memset(diskname, 0, sizeof(diskname));
    memset(bootname, 0, sizeof(bootname));
    kgets(diskname, sizeof(diskname));
    if (diskname[0] == '\n' || diskname[0] == '\0')
        goto getdiskname;

    /*
     * devopen() is picky.  Make sure it gets the sort of string it
     * wants.
     */
    (void)strcat(bootname, diskname);
    for (i = 0; bootname[i + 1] != '\0'; ++i)
        /* Nothing. */ ;
    if (bootname[i] < '0' || bootname[i] > '9') {
        printf("invalid disk name %s\n", diskname);
        goto getdiskname;
    }
    bootname[++i] = 'b';
    bootname[++i] = ':';
    (void)strcat(bootname, kernel_name);

    howto = RB_SINGLE;	/* _Always_ */

    printf("booting: %s -s\n", bootname);
    exec_hp300(bootname, (u_long)lowram, howto);
    printf("boot: %s\n", strerror(errno));
}
Пример #3
0
void menu(char *args) {
	char buf[64];

	menu_execute(args, 1);

	while (1) {
		kprintf("OS/161 kernel [? for menu]: ");
		kgets(buf, sizeof(buf));
		menu_execute(buf, 0);
	}
}
Пример #4
0
void
menu(char *args)
{
	char buf[64];

	menu_execute(args, 1);

	while (1) {
		kprintf("Kernel awaiting your command [? for menu]: ");
		kgets(buf, sizeof(buf));
		menu_execute(buf, 0);
	}
}
Пример #5
0
static int luaB__cgets (lua_State *L){
size_t nr;  /* number of chars actually read */
  char *p;
  luaL_Buffer b;
  luaL_buffinit(L, &b);
  p = luaL_prepbuffsize(&b, 255);  /* prepare buffer to read whole block */
kgets(p, 255);  
nr =  sizeof(p);  /* try to read 'n' chars */
  luaL_addsize(&b, nr);
  luaL_pushresult(&b);  /* close buffer */
  return (nr > 0);  /* true iff read something */

}
Пример #6
0
void
menu(char *args)
{
	char buf[64];

	menu_execute(args, 1);

	while (1) {
		kprintf("\033[1;33mOS/161 kernel \033[1;36m[? for menu]\033[5m: \033[0m");
		kgets(buf, sizeof(buf));
		menu_execute(buf, 0);
	}
}
Пример #7
0
void
menu(char *args)
{
	char buf[64];

	menu_execute(args, 1);

	while (1) {
		kprintf("testing the shellscript !!! /n");
		kprintf("OS/161 kernel [? for menu]: ");
		kgets(buf, sizeof(buf));
		menu_execute(buf, 0);
	}
}
Пример #8
0
void
menu(char *args)
{
	char buf[64];

	menu_execute(args, 1);

	while (1) {
		/*
		 * Defined in overwrite.h. If you want to change the kernel prompt, please
		 * do it in that file. Otherwise automated test testing will break.
		 */
		kprintf(KERNEL_PROMPT);
		kgets(buf, sizeof(buf));
		menu_execute(buf, 0);
	}
}
Пример #9
0
int
db_monitor(void)
{
	int tmp;
	int argc, flag;
	char *p, *argv[16];
	char line[1024];

	while(1) {
		printf("db> ");
		kgets(line, sizeof(line));

		flag = 0;
		for(p = line, argc = 0; *p != '\0'; p++) {
			if (*p != ' ' && *p != '\t') {
				if (!flag) {
					flag++;
					argv[argc++] = p;
				}
			} else {
				if (flag) {
					*p = '\0';
					flag = 0;
				}
			}
		}

		if (argc == 0)
			continue;

		tmp = 0;
		while (db_cmd[tmp].name != NULL) {
			if (!strcmp("continue", argv[0]))
				return 0;
			if (!strcmp(db_cmd[tmp].name, argv[0])) {
				(db_cmd[tmp].fcn)(argc, argv);
				break;
			}
			tmp++;
		}
		if (db_cmd[tmp].name == NULL)
			db_cmd_help(argc, argv);
	}
	return 0;
}
void main() {
	kputs("--DEBUG-- Hello world from kernel!\n");
	
	unsigned long i;
	kernelsp[0]=(unsigned long)kernel_stack[1];
	for(i=1;i<MSIM_CPU_NUM;i++) {
		send(MSIM_MASTER_ID, 0, 0);
		kernelsp[i]=(unsigned long)kernel_stack[i+1];
		send(i, 1, (uint32_t)cpu_stack[i+1]);
		send(i, 0, (uint32_t)slave_main);
	}
	
	cur_pid=pid_alloc();
	write_c0_entryhi(cur_pid);
	sc_num=SYS_EXEC;
	sc_args[0]="init";
	sc_pid=cur_pid;
	
	for(;;) {
		write_c0_compare(0);
		switch(sc_num) {
			case SYS_PUTS:
				kputs(sc_args[0]);
				sc_ret=0;
				break;
			case SYS_FORK:
				sc_ret=kfork();
				break;
			case SYS_EXEC:
				sc_ret=kexec(sc_args[0]);
				break;
			case SYS_GETS:
				sc_ret=kgets(sc_args[0], sc_args[1]);
				break;
		}
		pcb[sc_pid].gpr[ORD_V0]=sc_ret;
		cur_pid=sc_pid;
		next_process;
		sc_num=SYS_NONE;
		__to_user();
	}
}
Пример #11
0
int
opendisk(char *question, char *diskname, int len, char partition, int *fdp)
{
    char fulldiskname[64];
    int i;

getdiskname:
    printf("%s ", question);
    memset(diskname, 0, len);
    memset(fulldiskname, 0, sizeof(fulldiskname));
    kgets(diskname, sizeof(diskname));
    if (diskname[0] == '\n' || diskname[0] == '\0')
        goto getdiskname;

    /*
     * devopen() is picky.  Make sure it gets the sort of string it
     * wants.
     */
    memcpy(fulldiskname, diskname,
           len < sizeof(fulldiskname) ? len : sizeof(fulldiskname));
    for (i = 0; fulldiskname[i + 1] != '\0'; ++i)
        /* Nothing. */ ;
    if (fulldiskname[i] < '0' || fulldiskname[i] > '9') {
        printf("invalid disk name %s\n", diskname);
        goto getdiskname;
    }
    fulldiskname[++i] = partition;
    fulldiskname[++i] = ':';

    /*
     * We always open for writing.
     */
    if ((*fdp = open(fulldiskname, 1)) < 0) {
        printf("cannot open %s\n", diskname);
        return 1;
    }

    return 0;
}
Пример #12
0
/* 
 * Entry point for the kernel monitor. Monitor provides a simple shell with
 * a set of commands which starts when the OS boots.
 */
void monitor(void)
{
	char command_string[BUFFER_MAX_LENGTH];
	char *argv[ARG_COUNT_MAX];
	int argc = 0;

	while (true) {
		command_handler handler = NULL;
		
		kprintf("K> ");
		kgets(command_string);

		tokenize_command(command_string, &argc, argv);
		if (argc == 0)
			continue;

		handler = get_command_handler(argv[0]);
		if (handler == NULL)
			kprintf("command not found.\n");
		else
			handler(argc, argv);
	}
}
Пример #13
0
void
menu(char *args)
{
	char buf[64];

	/* BEGIN A3 SETUP */
	/* Initialize hacky semaphore solution to make menu thread 
	 * wait for command program to finish.
	 */
	cmd_sem = sem_create("cmdsem", 0);
	if (cmd_sem == NULL) {
		panic("menu: could not create cmd_sem\n");
	}
	/* END A3 SETUP */

	menu_execute(args, 1);

	while (1) {
		kprintf("OS/161 kernel [? for menu]: ");
		kgets(buf, sizeof(buf));
		menu_execute(buf, 0);
	}
}
Пример #14
0
void
bootmenu(void)
{
	char input[256];
	char *c;

	for (;;) {
		c = input;

		input[0] = '\0';
		printf("> ");
		kgets(input, sizeof(input));

		/*
		 * Skip leading whitespace.
		 */
		while (*c == ' ') {
			c++;
		}
		if (*c != '\0') {
			docommand(bootcmds, c);
		}
	}
}
Пример #15
0
void
main(void *ofw)
{
	int boothowto, i = 0, isfloppy, kboothowto;

	char kernel[PROM_MAX_PATH];
	char bootline[PROM_MAX_PATH];

	/* Initialize OpenFirmware */
	romp = ofw;
	prom_init();

	printf("\r>> %s, Revision %s\n", bootprog_name, bootprog_rev);

	/* Figure boot arguments */
	strncpy(bootdev, prom_getbootpath(), sizeof(bootdev) - 1);
	kboothowto = boothowto =
	    bootoptions(prom_getbootargs(), bootdev, kernel, bootline);
	isfloppy = bootdev_isfloppy(bootdev);

	for (;; *kernel = '\0') {
		if (boothowto & RB_ASKNAME) {
			char cmdline[PROM_MAX_PATH];

			printf("Boot: ");
			kgets(cmdline, sizeof(cmdline));

			if (!strcmp(cmdline,"exit") ||
			    !strcmp(cmdline,"halt")) {
				prom_halt();
			} else if (!strcmp(cmdline, "?") ||
				   !strcmp(cmdline, "help")) {
				help();
				continue;
			}

			boothowto  = bootoptions(cmdline, bootdev, kernel,
			    bootline);
			boothowto |= RB_ASKNAME;
			i = 0;
		}

		if (*kernel == '\0') {
			if (kernelnames[i] == NULL) {
				boothowto |= RB_ASKNAME;
				continue;
			}
			strncpy(kernel, kernelnames[i++], PROM_MAX_PATH);
		} else if (i == 0) {
			/*
			 * Kernel name was passed via command line -- ask user
			 * again if requested image fails to boot.
			 */
			boothowto |= RB_ASKNAME;
		}

		check_boot_config();
		start_kernel(kernel, bootline, ofw, isfloppy, kboothowto);

		/*
		 * Try next name from kernel name list if not in askname mode,
		 * enter askname on reaching list's end.
		 */
		if ((boothowto & RB_ASKNAME) == 0 && (kernelnames[i] != NULL)) {
			printf(": trying %s...\n", kernelnames[i]);
		} else {
			printf("\n");
			boothowto |= RB_ASKNAME;
		}
	}

	(void)printf("Boot failed! Exiting to the Firmware.\n");
	prom_halt();
}
Пример #16
0
int
usr_info(osdsc_t *od)
{
	static char	line[800];
	char		c, *p = line;

	printf("\nEnter os-type [.%s] root-fs [:a] kernel [%s]"
	       " options [none]:\n\033e", od->ostype, od->osname);
	kgets(p, sizeof(line));
	printf("\033f");

	for (;;) {
		while (isspace(*p))
			*p++ = '\0';

		switch (*p++) {
		case '\0':
			goto done;
		case ':':
			if ((c = *p) >= 'a' && c <= 'z')
				od->rootfs = c - 'a';
			else if (c >= 'A' && c <= 'Z')
				od->rootfs = c - ('A' - 27);
			else
				return -1;

			if (!od->rootfs)
				break;
			*p = 'b';
			/* FALLTHROUGH */
		  case '-':
			if ((c = *p) == 'a')
				od->boothowto &= ~RB_SINGLE;
			else if (c == 'b')
				od->boothowto |= RB_ASKNAME;
			else
				BOOT_FLAG(c, od->boothowto);
			break;
		  case '.':
			od->ostype = p;
			break;
		  case '/':
			od->osname = --p;
			break;
		  default:
			return -1;
		}

		while ((c = *p) && !isspace(c))
			p += 1;
	}

done:
	c = od->ostype[0];
	if (isupper(c))
		c = tolower(c);

	switch (c) {
	case 'n':		/* NetBSD */
		return 0;
	case 'l':		/* Linux  */
		return 0x10;
	case 'a':		/* ASV    */
		return 0x40;
	case 't':		/* TOS    */
		return 0x80;
	default:
		return -1;
	}
}
Пример #17
0
/*
 * Copy a miniroot image from an NFS server or tape to the `b' partition
 * of the specified disk.  Note, this assumes 512 byte sectors.
 */
void
miniroot(void)
{
    int sfd, dfd, i, nblks;
    char diskname[64], minirootname[128];
    char block[DEV_BSIZE];
    char tapename[64];
    int fileno, ignoreshread, eof, len;
    struct stat st;
    size_t xfersize;
    struct open_file *disk_ofp;
    extern struct open_file files[];

    /* Error message printed by opendisk() */
    if (opendisk("Disk for miniroot?", diskname, sizeof(diskname),
                 'b', &dfd))
        return;

    disk_ofp = &files[dfd];

getsource:
    printf("Source? (N)FS, (t)ape, (d)one > ");
    memset(line, 0, sizeof(line));
    kgets(line, sizeof(line));
    if (line[0] == '\0')
        goto getsource;

    switch (line[0]) {
    case 'n':
    case 'N':
name_of_nfs_miniroot:
        printf("Name of miniroot file? ");
        memset(line, 0, sizeof(line));
        memset(minirootname, 0, sizeof(minirootname));
        kgets(line, sizeof(line));
        if (line[0] == '\0')
            goto name_of_nfs_miniroot;
        (void)strcat(minirootname, "le0a:");
        (void)strcat(minirootname, line);
        if ((sfd = open(minirootname, 0)) < 0) {
            printf("can't open %s\n", line);
            return;
        }

        /*
         * Find out how big the miniroot is... we can't
         * check for size because it may be compressed.
         */
        ignoreshread = 1;
        if (fstat(sfd, &st) < 0) {
            printf("can't stat %s\n", line);
            goto done;
        }
        nblks = (int)(st.st_size / sizeof(block));

        printf("Copying miniroot from %s to %s...", line,
               diskname);
        break;

    case 't':
    case 'T':
name_of_tape_miniroot:
        printf("Which tape device? ");
        memset(line, 0, sizeof(line));
        memset(minirootname, 0, sizeof(minirootname));
        memset(tapename, 0, sizeof(tapename));
        kgets(line, sizeof(line));
        if (line[0] == '\0')
            goto name_of_tape_miniroot;
        strcat(minirootname, line);
        strcat(tapename, line);

        printf("File number (first == 1)? ");
        memset(line, 0, sizeof(line));
        kgets(line, sizeof(line));
        fileno = a2int(line);
        if (fileno < 1 || fileno > 8) {
            printf("Invalid file number: %s\n", line);
            goto getsource;
        }
        for (i = 0; i < sizeof(minirootname); ++i) {
            if (minirootname[i] == '\0')
                break;
        }
        if (i == sizeof(minirootname) ||
                (sizeof(minirootname) - i) < 8) {
            printf("Invalid device name: %s\n", tapename);
            goto getsource;
        }
        minirootname[i++] = 'a' + (fileno - 1);
        minirootname[i++] = ':';
        strcat(minirootname, "XXX");	/* lameness in open() */

        ignoreshread = 0;
        printf("Copy how many %d byte blocks? ", DEV_BSIZE);
        memset(line, 0, sizeof(line));
        kgets(line, sizeof(line));
        nblks = a2int(line);
        if (nblks < 0) {
            printf("Invalid block count: %s\n", line);
            goto getsource;
        } else if (nblks == 0) {
            printf("Zero blocks?  Ok, aborting.\n");
            return;
        }

        if ((sfd = open(minirootname, 0)) < 0) {
            printf("can't open %s file %c\n", tapename, fileno);
            return;
        }

        printf("Copying %s file %d to %s...", tapename, fileno,
               diskname);
        break;

    case 'd':
    case 'D':
        return;

    default:
        printf("Unknown source: %s\n", line);
        goto getsource;
    }

    /*
     * Copy loop...
     * This is fairly slow... if someone wants to speed it
     * up, they'll get no complaints from me.
     */
    for (i = 0, eof = 0; i < nblks || ignoreshread == 0; i++) {
        if ((len = read(sfd, block, sizeof(block))) < 0) {
            printf("Read error, errno = %d\n", errno);
            goto out;
        }

        /*
         * Check for end-of-file.
         */
        if (len == 0)
            goto done;
        else if (len < sizeof(block))
            eof = 1;

        if ((*disk_ofp->f_dev->dv_strategy)(disk_ofp->f_devdata,
                                            F_WRITE, i, len, block, &xfersize) || xfersize != len) {
            printf("Bad write at block %d, errno = %d\n",
                   i, errno);
            goto out;
        }

        if (eof)
            goto done;
    }
done:
    printf("done\n");

    printf("Successfully copied miniroot image.\n");

out:
    close(sfd);
    close(dfd);
}
Пример #18
0
/*
 * Do all the steps necessary to place a disklabel on a disk.
 * Note, this assumes 512 byte sectors.
 */
void
dsklabel(void)
{
    struct disklabel *lp;
    struct open_file *disk_ofp;
    int dfd, error;
    size_t xfersize;
    char block[DEV_BSIZE], diskname[64];
    extern struct open_file files[];

    printf(
        "You will be asked several questions about your disk, most of which\n"
        "require prior knowledge of the disk's geometry.  There is no easy way\n"
        "for the system to provide this information for you.  If you do not have\n"
        "this information, please consult your disk's manual or another\n"
        "informative source.\n\n");

    /* Error message printed by opendisk() */
    if (opendisk("Disk to label?", diskname, sizeof(diskname),
                 ('a' + RAW_PART), &dfd))
        return;

    disk_ofp = &files[dfd];

    memset(block, 0, sizeof(block));
    if ((error = (*disk_ofp->f_dev->dv_strategy)(disk_ofp->f_devdata,
                 F_READ, LABELSECTOR, sizeof(block), block, &xfersize)) != 0) {
        printf("cannot read disk %s, errno = %d\n", diskname, error);
        return;
    }

    printf("Successfully read %d bytes from %s\n", xfersize, diskname);

    lp = (struct disklabel *)((void *)(&block[LABELOFFSET]));

disklabel_loop:
    memset(line, 0, sizeof(line));
    printf("(z)ap, (e)dit, (s)how, (w)rite, (d)one > ");
    kgets(line, sizeof(line));
    if (line[0] == '\n' || line[0] == '\0')
        goto disklabel_loop;

    switch (line[0]) {
    case 'z':
    case 'Z': {
        char zap[DEV_BSIZE];
        memset(zap, 0, sizeof(zap));
        (void)(*disk_ofp->f_dev->dv_strategy)(disk_ofp->f_devdata,
                                              F_WRITE, LABELSECTOR, sizeof(zap), zap, &xfersize);
    }
    goto out;
    /* NOTREACHED */

    case 'e':
    case 'E':
        disklabel_edit(lp);
        break;

    case 's':
    case 'S':
        disklabel_show(lp);
        break;

    case 'w':
    case 'W':
        /*
         * Error message will be displayed by disklabel_write()
         */
        if (disklabel_write(block, sizeof(block), disk_ofp))
            goto out;
        else
            printf("Successfully wrote label to %s\n", diskname);
        break;

    case 'd':
    case 'D':
        goto out;
    /* NOTREACHED */

    default:
        printf("unknown command: %s\n", line);
    }

    goto disklabel_loop;
    /* NOTREACHED */

out:
    /*
     * Close disk.  Marks disk `not alive' so that partition
     * information will be reloaded upon next open.
     */
    (void)close(dfd);
}
Пример #19
0
void
graphics_install_vesa(uint16_t x, uint16_t y) {
	blog("Setting up VESA video controller...");

	/* VESA Structs */
	struct VesaControllerInfo *info = (void*)0x10000;
	struct VesaModeInfo *modeinfo = (void*)0x9000;

	/* 8086 Emulator Status */
	tRME_State *emu;
	void * lowCache;
	lowCache = malloc(RME_BLOCK_SIZE);
	memcpy(lowCache, NULL, RME_BLOCK_SIZE);
	emu = RME_CreateState();
	emu->Memory[0] = lowCache;
	for (int i = RME_BLOCK_SIZE; i < 0x100000; i += RME_BLOCK_SIZE) {
		emu->Memory[i/RME_BLOCK_SIZE] = (void*)i;
	}
	int ret, mode;

	/* Find modes */
	uint16_t * modes;
	memcpy(info->Signature, "VBE2", 4);
	emu->AX.W = 0x4F00;
	emu->ES   = 0x1000;
	emu->DI.W = 0;
	ret = RME_CallInt(emu, 0x10);
	if (info->Version < 0x200 || info->Version > 0x300) {
		bfinish(2);
		kprintf("\033[JYou have attempted to use the VESA/VBE2 driver\nwith a card that does not support VBE2.\n");
		kprintf("\nSystem responded to VBE request with version: 0x%x\n", info->Version);

		STOP;
	}
	modes = (void*)FP_TO_LINEAR(info->Videomodes.Segment,info->Videomodes.Offset);

	uint16_t best_x    = 0;
	uint16_t best_y    = 0;
	uint16_t best_b    = 0;
	uint16_t best_mode = 0;

	for (int i = 1; modes[i] != 0xFFFF; ++i) {
		emu->AX.W = 0x4F01;
		emu->CX.W = modes[i];
		emu->ES   = 0x0900;
		emu->DI.W = 0x0000;
		RME_CallInt(emu, 0x10);
#if PROMPT_FOR_MODE
		kprintf("%d = %dx%d:%d\n", i, modeinfo->Xres, modeinfo->Yres, modeinfo->bpp);
	}

	kprintf("Please select a mode: ");
	char buf[10];
	kgets(buf, 10);
	mode = atoi(buf);
#else
		if ((abs(modeinfo->Xres - x) < abs(best_x - x)) && (abs(modeinfo->Yres - y) < abs(best_y - y))) {
				best_mode = i;
				best_x = modeinfo->Xres;
				best_y = modeinfo->Yres;
				best_b = modeinfo->bpp;
		}
	}
Пример #20
0
/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Ralph Campbell.
 *
 * 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	8.1 (Berkeley) 6/10/93
 */

#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include <lib/libsa/loadfile.h>

#include <sys/param.h>
#include <sys/exec.h>
#include <sys/exec_ecoff.h>

#include "stand/common/common.h"
#include "stand/common/cfe_api.h"

#include <machine/autoconf.h>

#if !defined(UNIFIED_BOOTBLOCK) && !defined(SECONDARY_BOOTBLOCK)
#error not UNIFIED_BOOTBLOCK and not SECONDARY_BOOTBLOCK
#endif

char boot_file[128];
char boot_flags[128];
extern int debug;

struct bootinfo_v1 bootinfo;

paddr_t ffp_save, ptbr_save;

int debug;

char *kernelnames[] = {
	"netbsd",		"netbsd.gz",
	"netbsd.bak",		"netbsd.bak.gz",
	"netbsd.old",		"netbsd.old.gz",
	"onetbsd",		"onetbsd.gz",
	"netbsd.mips",		"netbsd.mips.gz",
	NULL
};

int
#if defined(UNIFIED_BOOTBLOCK)
main(long fwhandle,long evector,long fwentry,long fwseal)
#else /* defined(SECONDARY_BOOTBLOCK) */
main(long fwhandle,long fd,long fwentry)
#endif
{
	char *name, **namep;
	u_long marks[MARK_MAX];
	u_int32_t entry;
	int win;

	/* Init prom callback vector. */
	cfe_init(fwhandle,fwentry);

	/* Init the console device */
	init_console();

	/* print a banner */
	printf("\n");
	printf("NetBSD/sbmips " NETBSD_VERS " " BOOT_TYPE_NAME " Bootstrap, Revision %s\n",
	    bootprog_rev);
	printf("\n");

	/* set up the booted device descriptor */
#if defined(UNIFIED_BOOTBLOCK)
        if (!booted_dev_open()) {
                printf("Boot device (%s) open failed.\n",
		    booted_dev_name[0] ? booted_dev_name : "unknown");
                goto fail;
        }
#else /* defined(SECONDARY_BOOTBLOCK) */
	booted_dev_setfd(fd);
#endif

	printf("\n");

	boot_file[0] = 0;
	cfe_getenv("KERNEL_FILE",boot_file,sizeof(boot_file));

	boot_flags[0] = 0;
	cfe_getenv("BOOT_FLAGS",boot_flags,sizeof(boot_flags));

	if (boot_file[0] != 0)
		(void)printf("Boot file: %s\n", boot_file);
	(void)printf("Boot flags: %s\n", boot_flags);

	if (strchr(boot_flags, 'i') || strchr(boot_flags, 'I')) {
		printf("Boot file: ");
		kgets(boot_file, sizeof(boot_file));
	}

	memset(marks, 0, sizeof marks);
	if (boot_file[0] != '\0') {
		name = boot_file;
		win = loadfile(name, marks, LOAD_KERNEL) == 0;
	} else {
		name = NULL;	/* XXX gcc -Wuninitialized */
		for (namep = kernelnames, win = 0; *namep != NULL && !win;
		    namep++)
			win = loadfile(name = *namep, marks, LOAD_KERNEL) == 0;
	}

	entry = marks[MARK_ENTRY];
	booted_dev_close();
	printf("\n");
	if (!win)
		goto fail;

	(void)printf("Entering %s at 0x%lx...\n", name, (long)entry);

	cfe_flushcache(0);

	memset(&bootinfo, 0,sizeof(bootinfo));
	bootinfo.version = BOOTINFO_VERSION;
	bootinfo.reserved = 0;
	bootinfo.ssym = marks[MARK_SYM];
	bootinfo.esym = marks[MARK_END];
	strncpy(bootinfo.boot_flags,boot_flags,sizeof(bootinfo.boot_flags));
	strncpy(bootinfo.booted_kernel,name,sizeof(bootinfo.booted_kernel));
	bootinfo.fwhandle = fwhandle;
	bootinfo.fwentry = fwentry;

	(*(void (*)(long,long,long,long))entry)(fwhandle,
						BOOTINFO_MAGIC,
						(long)&bootinfo,
						fwentry);

	(void)printf("KERNEL RETURNED!\n");

fail:
	(void)printf("Boot failed!  Halting...\n");
	halt();
	return 1;
}