diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2014-03-25 22:25:44 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-06-28 12:55:30 +0200 |
commit | 4b9758c8ec6103c26228e1cda9731ab8bf1113e9 (patch) | |
tree | 64a9ba6685441e675bee388958e57fa0ad53f8dd | |
parent | fa5e2ae5645b3eb005931f60b5481ee7e478640e (diff) |
i386: improve the immediate console
Improve the immediate console to the point that it can be enabled and
display e.g. assertion failures from very early on (i.e. from
`c_boot_entry').
* device/cons.h (romgetc, romputc): New declarations.
* i386/configfrag.ac: Add configuration variable.
* i386/i386at/conf.c (dev_name_list): Add entry.
* i386/i386at/cons_conf.c (constab): Add entry.
* i386/i386at/immc.c: Add missing includes.
(immc_cnprobe, immc_cninit, immc_cngetc, immc_romputc): New functions.
(immc_cnputc): Fix signature, use virtual addresses.
* i386/i386at/immc.h: New file.
* i386/i386at/kd.c: Use `#if ENABLE_IMMEDIATE_CONSOLE'.
* i386/i386at/kd.h (kd_setpos): Add missing declaration.
* i386/i386at/model_dep.c (c_boot_entry): Install immediate console as
early boot console.
-rw-r--r-- | device/cons.h | 11 | ||||
-rw-r--r-- | i386/configfrag.ac | 4 | ||||
-rw-r--r-- | i386/i386at/conf.c | 6 | ||||
-rw-r--r-- | i386/i386at/cons_conf.c | 7 | ||||
-rw-r--r-- | i386/i386at/immc.c | 74 | ||||
-rw-r--r-- | i386/i386at/immc.h | 31 | ||||
-rw-r--r-- | i386/i386at/kd.c | 2 | ||||
-rw-r--r-- | i386/i386at/kd.h | 1 | ||||
-rw-r--r-- | i386/i386at/model_dep.c | 8 |
9 files changed, 130 insertions, 14 deletions
diff --git a/device/cons.h b/device/cons.h index 8ac796c..34f3bc5 100644 --- a/device/cons.h +++ b/device/cons.h @@ -54,4 +54,15 @@ extern int cngetc(void); extern int cnmaygetc(void); extern void cnputc(char); + +/* + * ROM getc/putc primitives. + * On some architectures, the boot ROM provides basic character input/output + * routines that can be used before devices are configured or virtual memory + * is enabled. This can be useful to debug (or catch panics from) code early + * in the bootstrap procedure. + */ +extern int (*romgetc)(char c); +extern void (*romputc)(char c); + #endif /* _DEVICE_CONS_H */ diff --git a/i386/configfrag.ac b/i386/configfrag.ac index 1eaabca..48744b1 100644 --- a/i386/configfrag.ac +++ b/i386/configfrag.ac @@ -73,6 +73,10 @@ AC_DEFINE_UNQUOTED([NLPR], [$nlpr], [NLPR]) # Options. # +# The immediate console, useful for debugging early system +# initialization. Disabled by default. +AC_DEFINE([ENABLE_IMMEDIATE_CONSOLE], [0], [ENABLE_IMMEDIATE_CONSOLE]) + AC_ARG_ENABLE([lpr], AS_HELP_STRING([--enable-lpr], [lpr device; on ix86-at enabled by default])) [case $host_platform:$host_cpu in diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c index ab4f680..fe7c7c0 100644 --- a/i386/i386at/conf.c +++ b/i386/i386at/conf.c @@ -87,6 +87,12 @@ struct dev_ops dev_name_list[] = nodev }, #ifndef MACH_HYP +#if ENABLE_IMMEDIATE_CONSOLE + { "immc", nulldev_open, nulldev_close, nulldev_read, + nulldev_write, nulldev_getstat, nulldev_setstat, + nomap, nodev, nulldev, nulldev_portdeath, 0, + nodev }, +#endif /* ENABLE_IMMEDIATE_CONSOLE */ { kdname, kdopen, kdclose, kdread, kdwrite, kdgetstat, kdsetstat, kdmmap, nodev, nulldev, kdportdeath, 0, diff --git a/i386/i386at/cons_conf.c b/i386/i386at/cons_conf.c index cf42bb6..1d7dd38 100644 --- a/i386/i386at/cons_conf.c +++ b/i386/i386at/cons_conf.c @@ -39,6 +39,10 @@ #endif #endif /* MACH_HYP */ +#if ENABLE_IMMEDIATE_CONSOLE +#include "immc.h" +#endif /* ENABLE_IMMEDIATE_CONSOLE */ + /* * The rest of the consdev fields are filled in by the respective * cnprobe routine. @@ -47,6 +51,9 @@ struct consdev constab[] = { #ifdef MACH_HYP {"hyp", hypcnprobe, hypcninit, hypcngetc, hypcnputc}, #else /* MACH_HYP */ +#if ENABLE_IMMEDIATE_CONSOLE + {"immc", immc_cnprobe, immc_cninit, immc_cngetc, immc_cnputc}, +#endif /* ENABLE_IMMEDIATE_CONSOLE */ {"kd", kdcnprobe, kdcninit, kdcngetc, kdcnputc}, #if NCOM > 0 {"com", comcnprobe, comcninit, comcngetc, comcnputc}, diff --git a/i386/i386at/immc.c b/i386/i386at/immc.c index e0837f2..ea95169 100644 --- a/i386/i386at/immc.c +++ b/i386/i386at/immc.c @@ -21,8 +21,11 @@ * Author: Bryan Ford, University of Utah CSL */ -#ifdef ENABLE_IMMEDIATE_CONSOLE +#if ENABLE_IMMEDIATE_CONSOLE +#include <device/cons.h> +#include <mach/boolean.h> +#include <i386/vm_param.h> #include <string.h> /* This is a special "feature" (read: kludge) @@ -35,22 +38,65 @@ boolean_t immediate_console_enable = TRUE; -void -immc_cnputc(unsigned char c) +/* + * XXX we assume that pcs *always* have a console + */ +int +immc_cnprobe(struct consdev *cp) +{ + int maj, unit, pri; + + maj = 0; + unit = 0; + pri = CN_INTERNAL; + + cp->cn_dev = makedev(maj, unit); + cp->cn_pri = pri; + return 0; +} + +int +immc_cninit(struct consdev *cp) +{ + return 0; +} + +int immc_cnmaygetc(void) +{ + return -1; +} + +int +immc_cngetc(dev_t dev, int wait) +{ + if (wait) { + int c; + while ((c = immc_cnmaygetc()) < 0) + continue; + return c; + } + else + return immc_cnmaygetc(); +} + +int +immc_cnputc(dev_t dev, int c) { static int ofs = -1; if (!immediate_console_enable) - return; + return -1; if (ofs < 0) { ofs = 0; - immc_cnputc('\n'); + immc_cnputc(dev, '\n'); } - else if (c == '\n') + + if (c == '\n') { - memmove((void *)0xb8000, (void *)0xb8000+80*2, 80*2*24); - memset((void *)(0xb8000+80*2*24), 0, 80*2); + memmove((void *) phystokv(0xb8000), + (void *) phystokv(0xb8000+80*2), 80*2*24); + memset((void *) phystokv((0xb8000+80*2*24)), 0, 80*2); ofs = 0; } else @@ -59,20 +105,22 @@ immc_cnputc(unsigned char c) if (ofs >= 80) { - immc_cnputc('\r'); - immc_cnputc('\n'); + immc_cnputc(dev, '\r'); + immc_cnputc(dev, '\n'); } - p = (void*)0xb8000 + 80*2*24 + ofs*2; + p = (void *) phystokv(0xb8000 + 80*2*24 + ofs*2); p[0] = c; p[1] = 0x0f; ofs++; } + return 0; } -int immc_cnmaygetc(void) +void +immc_romputc(char c) { - return -1; + immc_cnputc (0, c); } #endif /* ENABLE_IMMEDIATE_CONSOLE */ diff --git a/i386/i386at/immc.h b/i386/i386at/immc.h new file mode 100644 index 0000000..dc802c8 --- /dev/null +++ b/i386/i386at/immc.h @@ -0,0 +1,31 @@ +/* Declarations for the immediate console. + + Copyright (C) 2015 Free Software Foundation, Inc. + + This file is part of the GNU Mach. + + The GNU Mach is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Mach is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Mach. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _IMMC_H_ +#define _IMMC_H_ + +#include <sys/types.h> + +int immc_cnprobe(struct consdev *cp); +int immc_cninit(struct consdev *cp); +int immc_cngetc(dev_t dev, int wait); +int immc_cnputc(dev_t dev, int c); +void immc_romputc(char c); + +#endif /* _IMMC_H_ */ diff --git a/i386/i386at/kd.c b/i386/i386at/kd.c index bbb0023..5656e83 100644 --- a/i386/i386at/kd.c +++ b/i386/i386at/kd.c @@ -1162,7 +1162,7 @@ kdinit(void) kd_senddata(k_comm); kd_initialized = TRUE; -#ifdef ENABLE_IMMEDIATE_CONSOLE +#if ENABLE_IMMEDIATE_CONSOLE /* Now that we're set up, we no longer need or want the immediate console. */ { diff --git a/i386/i386at/kd.h b/i386/i386at/kd.h index 4ac93c7..0cfed69 100644 --- a/i386/i386at/kd.h +++ b/i386/i386at/kd.h @@ -740,6 +740,7 @@ extern int kdcninit(struct consdev *cp); extern int kdcngetc(dev_t dev, int wait); extern int kdcnmaygetc (void); extern int kdcnputc(dev_t dev, int c); +extern void kd_setpos(csrpos_t newpos); extern void kd_slmwd (void *start, int count, int value); extern void kd_slmscu (void *from, void *to, int count); diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c index 03a9f15..fdf983b 100644 --- a/i386/i386at/model_dep.c +++ b/i386/i386at/model_dep.c @@ -77,6 +77,10 @@ #include <xen/xen.h> #endif /* MACH_XEN */ +#if ENABLE_IMMEDIATE_CONSOLE +#include "immc.h" +#endif /* ENABLE_IMMEDIATE_CONSOLE */ + /* Location of the kernel's symbol table. Both of these are 0 if none is available. */ #if MACH_KDB @@ -541,6 +545,10 @@ i386at_init(void) */ void c_boot_entry(vm_offset_t bi) { +#if ENABLE_IMMEDIATE_CONSOLE + romputc = immc_romputc; +#endif /* ENABLE_IMMEDIATE_CONSOLE */ + /* Stash the boot_image_info pointer. */ boot_info = *(typeof(boot_info)*)phystokv(bi); int cpu_type; |