summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2014-03-25 22:25:44 +0100
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-06-28 12:55:30 +0200
commit4b9758c8ec6103c26228e1cda9731ab8bf1113e9 (patch)
tree64a9ba6685441e675bee388958e57fa0ad53f8dd
parentfa5e2ae5645b3eb005931f60b5481ee7e478640e (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.h11
-rw-r--r--i386/configfrag.ac4
-rw-r--r--i386/i386at/conf.c6
-rw-r--r--i386/i386at/cons_conf.c7
-rw-r--r--i386/i386at/immc.c74
-rw-r--r--i386/i386at/immc.h31
-rw-r--r--i386/i386at/kd.c2
-rw-r--r--i386/i386at/kd.h1
-rw-r--r--i386/i386at/model_dep.c8
9 files changed, 130 insertions, 14 deletions
diff --git a/device/cons.h b/device/cons.h
index 8ac796cd..34f3bc56 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 1eaabcad..48744b12 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 ab4f6807..fe7c7c09 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 cf42bb63..1d7dd387 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 e0837f2c..ea951690 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 00000000..dc802c84
--- /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 bbb00239..5656e830 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 4ac93c7b..0cfed695 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 03a9f15d..fdf983b9 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;