From da2ee59bfdc3dbce585ab2f91d69b8c228bf7779 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Tue, 25 Mar 2014 22:25:44 +0100 Subject: [PATCH gnumach 2/3] i386: improve the immediate console * i386/configfrag.ac * i386/i386at/conf.c * i386/i386at/cons_conf.c * i386/i386at/immc.c * i386/i386at/kd.c --- device/cons.h | 11 ++++++++ i386/configfrag.ac | 4 +++ i386/i386at/conf.c | 6 +++++ i386/i386at/cons_conf.c | 7 +++++ i386/i386at/immc.c | 69 +++++++++++++++++++++++++++++++++++++++++-------- i386/i386at/immc.h | 5 ++++ i386/i386at/kd.c | 2 +- i386/i386at/model_dep.c | 8 ++++++ 8 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 i386/i386at/immc.h 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..9101c34 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 +#include +#include #include /* This is a special "feature" (read: kludge) @@ -35,8 +38,49 @@ boolean_t immediate_console_enable = TRUE; +/* + * 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(); +} + void -immc_cnputc(unsigned char c) +immc_cnputc(dev_t dev, unsigned char c) { static int ofs = -1; @@ -45,12 +89,14 @@ immc_cnputc(unsigned char c) 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,21 @@ 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++; } } -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..af96a9b --- /dev/null +++ b/i386/i386at/immc.h @@ -0,0 +1,5 @@ +int immc_cnprobe(struct consdev *cp); +int immc_cninit(struct consdev *cp); +int immc_cngetc(dev_t dev, int wait); +void immc_cnputc(dev_t dev, unsigned char c); +void immc_romputc(char c); 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/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 #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; -- 2.1.4