示例#1
0
PUBLIC __dead void arch_shutdown(int how)
{
	u16_t magic;
	vm_stop();

	/* Mask all interrupts, including the clock. */
	outb( INT_CTLMASK, ~0);

	if(minix_panicing) {
		unsigned char unused_ch;
		/* We're panicing? Then retrieve and decode currently
		 * loaded segment selectors.
		 */
		printseg("cs: ", 1, get_cpulocal_var(proc_ptr), read_cs());
		printseg("ds: ", 0, get_cpulocal_var(proc_ptr), read_ds());
		if(read_ds() != read_ss()) {
			printseg("ss: ", 0, NULL, read_ss());
		}

		/* Printing is done synchronously over serial. */
		if (do_serial_debug)
			reset();

		/* Print accumulated diagnostics buffer and reset. */
		mb_cls();
		mb_print("Minix panic. System diagnostics buffer:\n\n");
		mb_print(kmess_buf);
		mb_print("\nSystem has panicked, press any key to reboot");
		while (!mb_read_char(&unused_ch))
			;
		reset();
	}

#if USE_BOOTPARAM
	if (how == RBT_DEFAULT) {
		how = mon_return ? RBT_HALT : RBT_RESET;
	}

	if(how != RBT_RESET) {
		/* return to boot monitor */

		outb( INT_CTLMASK, 0);            
		outb( INT2_CTLMASK, 0);
        
		/* Return to the boot monitor. Set
		 * the program if not already done.
		 */
		if (how != RBT_MONITOR)
			arch_set_params("", 1);

		if (mon_return)
			arch_monitor();

		/* monitor command with no monitor: reset or poweroff 
		 * depending on the parameters
		 */
		if (how == RBT_MONITOR) {
			how = RBT_RESET;
		}
	}

	switch (how) {
		case RBT_REBOOT:
		case RBT_RESET:
			/* Reset the system by forcing a processor shutdown. 
			 * First stop the BIOS memory test by setting a soft
			 * reset flag.
			 */
			magic = STOP_MEM_CHECK;
			phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR,
       		 	SOFT_RESET_FLAG_SIZE);
			reset();
			NOT_REACHABLE;

		case RBT_HALT:
			/* Poweroff without boot monitor */
			arch_bios_poweroff();
			NOT_REACHABLE;

		case RBT_PANIC:
			/* Allow user to read panic message */
			for (; ; ) halt_cpu();
			NOT_REACHABLE;

		default:	
			/* Not possible! trigger panic */
			assert(how != RBT_MONITOR);
			assert(how != RBT_DEFAULT);
			assert(how < RBT_INVALID);
			panic("unexpected value for how: %d", how);
			NOT_REACHABLE;
	}
#else /* !USE_BOOTPARAM */
	/* Poweroff without boot monitor */
	arch_bios_poweroff();
#endif

	NOT_REACHABLE;
}
示例#2
0
PUBLIC __dead void arch_shutdown(int how)
{
    static char mybuffer[sizeof(params_buffer)];
    u16_t magic;
    vm_stop();

    /* Mask all interrupts, including the clock. */
    outb( INT_CTLMASK, ~0);

    if(minix_panicing) {
        /* We're panicing? Then retrieve and decode currently
         * loaded segment selectors.
         */
        printseg("cs: ", 1, proc_ptr, read_cs());
        printseg("ds: ", 0, proc_ptr, read_ds());
        if(read_ds() != read_ss()) {
            printseg("ss: ", 0, NULL, read_ss());
        }
    }

    if (how == RBT_DEFAULT) {
        how = mon_return ? RBT_HALT : RBT_RESET;
    }

    if(how != RBT_RESET) {
        /* return to boot monitor */

        outb( INT_CTLMASK, 0);
        outb( INT2_CTLMASK, 0);

        /* Return to the boot monitor. Set
         * the program if not already done.
         */
        if (how != RBT_MONITOR)
            arch_set_params("", 1);
        if(minix_panicing) {
            int source, dest;
            const char *lead = "echo \\n*** kernel messages:\\n";
            const int leadlen = strlen(lead);
            strcpy(mybuffer, lead);

#define DECSOURCE source = (source - 1 + _KMESS_BUF_SIZE) % _KMESS_BUF_SIZE

            dest = sizeof(mybuffer)-1;
            mybuffer[dest--] = '\0';

            source = kmess.km_next;
            DECSOURCE;

            while(dest >= leadlen) {
                const char c = kmess.km_buf[source];
                if(c == '\n') {
                    mybuffer[dest--] = 'n';
                    mybuffer[dest] = '\\';
                } else if(isprint(c) &&
                          c != '\'' && c != '"' &&
                          c != '\\' && c != ';') {
                    mybuffer[dest] = c;
                } else	mybuffer[dest] = ' ';

                DECSOURCE;
                dest--;
            }

            arch_set_params(mybuffer, strlen(mybuffer)+1);
        }
        if (mon_return)
            arch_monitor();

        /* monitor command with no monitor: reset or poweroff
         * depending on the parameters
         */
        if (how == RBT_MONITOR) {
            mybuffer[0] = '\0';
            arch_get_params(mybuffer, sizeof(mybuffer));
            if (strstr(mybuffer, "boot") ||
                    strstr(mybuffer, "menu") ||
                    strstr(mybuffer, "reset"))
                how = RBT_RESET;
            else
                how = RBT_HALT;
        }
    }

    switch (how) {
    case RBT_REBOOT:
    case RBT_RESET:
        /* Reset the system by forcing a processor shutdown.
         * First stop the BIOS memory test by setting a soft
         * reset flag.
         */
        magic = STOP_MEM_CHECK;
        phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR,
                  SOFT_RESET_FLAG_SIZE);
        reset();
        NOT_REACHABLE;

    case RBT_HALT:
        /* Poweroff without boot monitor */
        arch_bios_poweroff();
        NOT_REACHABLE;

    case RBT_PANIC:
        /* Allow user to read panic message */
        for (; ; ) halt_cpu();
        NOT_REACHABLE;

    default:
        /* Not possible! trigger panic */
        assert(how != RBT_MONITOR);
        assert(how != RBT_DEFAULT);
        assert(how < RBT_INVALID);
        panic("unexpected value for how: %d", how);
        NOT_REACHABLE;
    }

    NOT_REACHABLE;
}