summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKazutaka YOKOTA <yokota@FreeBSD.org>1997-06-22 12:04:36 +0000
committerKazutaka YOKOTA <yokota@FreeBSD.org>1997-06-22 12:04:36 +0000
commit124ff4169d95f0547957440cb6b6788625d12cf4 (patch)
treeefbcadcad076f3cff54781a429e12f88e0ba2b29
parentc222d4bb39b9752388a06e69d8666cc25c0d7649 (diff)
Notes
-rw-r--r--sys/dev/syscons/syscons.c230
-rw-r--r--sys/i386/isa/syscons.c230
-rw-r--r--sys/isa/syscons.c230
3 files changed, 489 insertions, 201 deletions
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 5d01115481b9..5df41907a37a 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.215 1997/05/07 20:02:38 peter Exp $
+ * $Id: syscons.c,v 1.216 1997/05/15 05:43:57 yokota Exp $
*/
#include "sc.h"
@@ -111,6 +111,7 @@ static char write_in_progress = FALSE;
static char blink_in_progress = FALSE;
static int blinkrate = 0;
u_int crtc_addr = MONO_BASE;
+ char crtc_type = KD_MONO;
char crtc_vga = FALSE;
static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0;
static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0;
@@ -171,10 +172,15 @@ static const int nsccons = MAXCONS+2;
+ (offset)) % (scp->history_size)))
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
+/* this should really be in `rtc.h' */
+#define RTC_EQUIPMENT 0x14
+
/* prototypes */
static int scattach(struct isa_device *dev);
static int scparam(struct tty *tp, struct termios *t);
static int scprobe(struct isa_device *dev);
+static int scvidprobe(int unit, int flags);
+static int sckbdprobe(int unit, int flags);
static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
static void scinit(void);
@@ -303,17 +309,125 @@ move_crsr(scr_stat *scp, int x, int y)
static int
scprobe(struct isa_device *dev)
{
+ if (!scvidprobe(dev->id_unit, dev->id_flags)) {
+ if (bootverbose)
+ printf("sc%d: no video adapter is found.\n", dev->id_unit);
+ return (0);
+ }
+
+ sc_port = dev->id_iobase;
+ if (sckbdprobe(dev->id_unit, dev->id_flags))
+ return (IO_KBDSIZE);
+ else
+ return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+}
+
+/* probe video adapters, return TRUE if found */
+static int
+scvidprobe(int unit, int flags)
+{
+ /*
+ * XXX don't try to `printf' anything here, the console may not have
+ * been configured yet.
+ */
+ u_short volatile *cp;
+ u_short was;
+ u_long pa;
+ u_long segoff;
+
+ /* do this test only once */
+ if (init_done != COLD)
+ return (Crtat != 0);
+
+ /*
+ * Finish defaulting crtc variables for a mono screen. Crtat is a
+ * bogus common variable so that it can be shared with pcvt, so it
+ * can't be statically initialized. XXX.
+ */
+ Crtat = (u_short *)MONO_BUF;
+ crtc_type = KD_MONO;
+ /* If CGA memory seems to work, switch to color. */
+ cp = (u_short *)CGA_BUF;
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp == 0xA55A) {
+ Crtat = (u_short *)CGA_BUF;
+ crtc_addr = COLOR_BASE;
+ crtc_type = KD_CGA;
+ } else {
+ cp = Crtat;
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp != 0xA55A) {
+ /* no screen at all, bail out */
+ Crtat = 0;
+ return FALSE;
+ }
+ }
+ *cp = was;
+
+ /*
+ * Check rtc and BIOS date area.
+ * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy
+ * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are
+ * zeros for EGA and VGA. However, the EGA/VGA BIOS will set
+ * these bits in BIOSDATA_EQUIPMENT according to the monitor
+ * type detected.
+ */
+ switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
+ case 0: /* EGA/VGA, or nothing */
+ crtc_type = KD_EGA;
+ /* the color adapter may be in the 40x25 mode... XXX */
+ break;
+ case 1: /* CGA 40x25 */
+ /* switch to the 80x25 mode? XXX */
+ /* FALL THROUGH */
+ case 2: /* CGA 80x25 */
+ /* `crtc_type' has already been set... */
+ /* crtc_type = KD_CGA; */
+ break;
+ case 3: /* MDA */
+ /* `crtc_type' has already been set... */
+ /* crtc_type = KD_MONO; */
+ break;
+ }
+
+ /* is this a VGA or higher ? */
+ outb(crtc_addr, 7);
+ if (inb(crtc_addr) == 7) {
+
+ crtc_type = KD_VGA;
+ crtc_vga = TRUE;
+ read_vgaregs(vgaregs);
+
+ /* Get the BIOS video mode pointer */
+ segoff = *(u_long *)pa_to_va(0x4a8);
+ pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
+ if (ISMAPPED(pa, sizeof(u_long))) {
+ segoff = *(u_long *)pa_to_va(pa);
+ pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
+ if (ISMAPPED(pa, 64))
+ video_mode_ptr = (char *)pa_to_va(pa);
+ }
+ }
+
+ return TRUE;
+}
+
+/* probe the keyboard, return TRUE if found */
+static int
+sckbdprobe(int unit, int flags)
+{
int codeset;
int c = -1;
int m;
- sc_port = dev->id_iobase;
sc_kbdc = kbdc_open(sc_port);
if (!kbdc_lock(sc_kbdc, TRUE)) {
/* driver error? */
- printf("sc%d: unable to lock the controller.\n", dev->id_unit);
- return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+ printf("sc%d: unable to lock the controller.\n", unit);
+ return ((flags & DETECT_KBD) ? FALSE : TRUE);
}
/* discard anything left after UserConfig */
@@ -324,26 +438,35 @@ scprobe(struct isa_device *dev)
c = get_controller_command_byte(sc_kbdc);
if (c == -1) {
/* CONTROLLER ERROR */
- printf("sc%d: unable to get the current command byte value.\n",
- dev->id_unit);
+ printf("sc%d: unable to get the current command byte value.\n", unit);
goto fail;
}
if (bootverbose)
printf("sc%d: the current keyboard controller command byte %04x\n",
- dev->id_unit, c);
+ unit, c);
#if 0
/* override the keyboard lock switch */
c |= KBD_OVERRIDE_KBD_LOCK;
#endif
+ /*
+ * The keyboard may have been screwed up by the boot block.
+ * We may just be able to recover from error by testing the controller
+ * and the keyboard port. The controller command byte needs to be saved
+ * before this recovery operation, as some controllers seem to set
+ * the command byte to particular values.
+ */
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+
/* enable the keyboard port, but disable the keyboard intr. */
if (!set_controller_command_byte(sc_kbdc,
- KBD_KBD_CONTROL_BITS,
+ KBD_KBD_CONTROL_BITS,
KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT)) {
/* CONTROLLER ERROR
* there is very little we can do...
*/
- printf("sc%d: unable to set the command byte.\n", dev->id_unit);
+ printf("sc%d: unable to set the command byte.\n", unit);
goto fail;
}
@@ -354,7 +477,7 @@ scprobe(struct isa_device *dev)
* during the boot process.
*/
codeset = -1;
- if (dev->id_flags & XT_KEYBD)
+ if (flags & XT_KEYBD)
/* the user says there is a XT keyboard */
codeset = 1;
#ifdef DETECT_XT_KEYBOARD
@@ -365,7 +488,7 @@ scprobe(struct isa_device *dev)
codeset = read_kbd_data(sc_kbdc);
}
if (bootverbose)
- printf("sc%d: keyboard scancode set %d\n", dev->id_unit, codeset);
+ printf("sc%d: keyboard scancode set %d\n", unit, codeset);
#endif /* DETECT_XT_KEYBOARD */
/* reset keyboard hardware */
@@ -386,7 +509,7 @@ scprobe(struct isa_device *dev)
* the keyboard may still exist (see above).
*/
if (bootverbose)
- printf("sc%d: failed to reset the keyboard.\n", dev->id_unit);
+ printf("sc%d: failed to reset the keyboard.\n", unit);
goto fail;
}
@@ -405,7 +528,7 @@ scprobe(struct isa_device *dev)
* The XT kbd isn't usable unless the proper scan code set
* is selected.
*/
- printf("sc%d: unable to set the XT keyboard mode.\n", dev->id_unit);
+ printf("sc%d: unable to set the XT keyboard mode.\n", unit);
goto fail;
}
}
@@ -417,24 +540,23 @@ scprobe(struct isa_device *dev)
/* CONTROLLER ERROR
* This is serious; we are left with the disabled keyboard intr.
*/
- printf("sc%d: unable to enable the keyboard port and intr.\n",
- dev->id_unit);
+ printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
goto fail;
}
succeed:
kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
kbdc_lock(sc_kbdc, FALSE);
- return (IO_KBDSIZE);
+ return TRUE;
fail:
if (c != -1)
/* try to restore the command byte as before, if possible */
set_controller_command_byte(sc_kbdc, 0xff, c);
kbdc_set_device_mask(sc_kbdc,
- (dev->id_flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
+ (flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
kbdc_lock(sc_kbdc, FALSE);
- return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+ return FALSE;
}
#if NAPM > 0
@@ -508,16 +630,28 @@ scattach(struct isa_device *dev)
}
printf("sc%d: ", dev->id_unit);
- if (crtc_vga)
+ switch(crtc_type) {
+ case KD_VGA:
if (crtc_addr == MONO_BASE)
printf("VGA mono");
else
printf("VGA color");
- else
+ break;
+ case KD_EGA:
if (crtc_addr == MONO_BASE)
- printf("MDA/hercules");
+ printf("EGA mono");
else
- printf("CGA/EGA");
+ printf("EGA color");
+ break;
+ case KD_CGA:
+ printf("CGA");
+ break;
+ case KD_MONO:
+ case KD_HERCULES:
+ default:
+ printf("MDA/hercules");
+ break;
+ }
printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags);
#if NAPM > 0
@@ -745,13 +879,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
return 0;
case CONS_CURRENT: /* get current adapter type */
- if (crtc_vga)
- *(int*)data = KD_VGA;
- else
- if (crtc_addr == MONO_BASE)
- *(int*)data = KD_MONO;
- else
- *(int*)data = KD_CGA;
+ *(int *)data = crtc_type;
return 0;
case CONS_GET: /* get current video mode */
@@ -1465,6 +1593,11 @@ sccnprobe(struct consdev *cp)
return;
}
+ if (!scvidprobe(dvp->id_unit, dvp->id_flags)) {
+ cp->cn_pri = CN_DEAD;
+ return;
+ }
+
/* initialize required fields */
cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
cp->cn_pri = CN_INTERNAL;
@@ -2395,31 +2528,12 @@ outloop:
static void
scinit(void)
{
- u_short volatile *cp;
- u_short was;
u_int hw_cursor;
u_int i;
if (init_done != COLD)
return;
init_done = WARM;
- /*
- * Finish defaulting crtc variables for a mono screen. Crtat is a
- * bogus common variable so that it can be shared with pcvt, so it
- * can't be statically initialized. XXX.
- */
- Crtat = (u_short *)MONO_BUF;
- /*
- * If CGA memory seems to work, switch to color.
- */
- cp = (u_short *)CGA_BUF;
- was = *cp;
- *cp = (u_short) 0xA55A;
- if (*cp == 0xA55A) {
- Crtat = (u_short *)CGA_BUF;
- crtc_addr = COLOR_BASE;
- }
- *cp = was;
/*
* Ensure a zero start address. This is mainly to recover after
@@ -2451,25 +2565,7 @@ scinit(void)
outb(crtc_addr, 15);
outb(crtc_addr + 1, 0xff);
- /* is this a VGA or higher ? */
- outb(crtc_addr, 7);
- if (inb(crtc_addr) == 7) {
- u_long pa;
- u_long segoff;
-
- crtc_vga = TRUE;
- read_vgaregs(vgaregs);
-
- /* Get the BIOS video mode pointer */
- segoff = *(u_long *)pa_to_va(0x4a8);
- pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
- if (ISMAPPED(pa, sizeof(u_long))) {
- segoff = *(u_long *)pa_to_va(pa);
- pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
- if (ISMAPPED(pa, 64))
- video_mode_ptr = (char *)pa_to_va(pa);
- }
- }
+ /* set up the first console */
current_default = &user_default;
console[0] = &main_console;
init_scp(console[0]);
diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c
index 5d01115481b9..5df41907a37a 100644
--- a/sys/i386/isa/syscons.c
+++ b/sys/i386/isa/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.215 1997/05/07 20:02:38 peter Exp $
+ * $Id: syscons.c,v 1.216 1997/05/15 05:43:57 yokota Exp $
*/
#include "sc.h"
@@ -111,6 +111,7 @@ static char write_in_progress = FALSE;
static char blink_in_progress = FALSE;
static int blinkrate = 0;
u_int crtc_addr = MONO_BASE;
+ char crtc_type = KD_MONO;
char crtc_vga = FALSE;
static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0;
static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0;
@@ -171,10 +172,15 @@ static const int nsccons = MAXCONS+2;
+ (offset)) % (scp->history_size)))
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
+/* this should really be in `rtc.h' */
+#define RTC_EQUIPMENT 0x14
+
/* prototypes */
static int scattach(struct isa_device *dev);
static int scparam(struct tty *tp, struct termios *t);
static int scprobe(struct isa_device *dev);
+static int scvidprobe(int unit, int flags);
+static int sckbdprobe(int unit, int flags);
static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
static void scinit(void);
@@ -303,17 +309,125 @@ move_crsr(scr_stat *scp, int x, int y)
static int
scprobe(struct isa_device *dev)
{
+ if (!scvidprobe(dev->id_unit, dev->id_flags)) {
+ if (bootverbose)
+ printf("sc%d: no video adapter is found.\n", dev->id_unit);
+ return (0);
+ }
+
+ sc_port = dev->id_iobase;
+ if (sckbdprobe(dev->id_unit, dev->id_flags))
+ return (IO_KBDSIZE);
+ else
+ return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+}
+
+/* probe video adapters, return TRUE if found */
+static int
+scvidprobe(int unit, int flags)
+{
+ /*
+ * XXX don't try to `printf' anything here, the console may not have
+ * been configured yet.
+ */
+ u_short volatile *cp;
+ u_short was;
+ u_long pa;
+ u_long segoff;
+
+ /* do this test only once */
+ if (init_done != COLD)
+ return (Crtat != 0);
+
+ /*
+ * Finish defaulting crtc variables for a mono screen. Crtat is a
+ * bogus common variable so that it can be shared with pcvt, so it
+ * can't be statically initialized. XXX.
+ */
+ Crtat = (u_short *)MONO_BUF;
+ crtc_type = KD_MONO;
+ /* If CGA memory seems to work, switch to color. */
+ cp = (u_short *)CGA_BUF;
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp == 0xA55A) {
+ Crtat = (u_short *)CGA_BUF;
+ crtc_addr = COLOR_BASE;
+ crtc_type = KD_CGA;
+ } else {
+ cp = Crtat;
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp != 0xA55A) {
+ /* no screen at all, bail out */
+ Crtat = 0;
+ return FALSE;
+ }
+ }
+ *cp = was;
+
+ /*
+ * Check rtc and BIOS date area.
+ * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy
+ * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are
+ * zeros for EGA and VGA. However, the EGA/VGA BIOS will set
+ * these bits in BIOSDATA_EQUIPMENT according to the monitor
+ * type detected.
+ */
+ switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
+ case 0: /* EGA/VGA, or nothing */
+ crtc_type = KD_EGA;
+ /* the color adapter may be in the 40x25 mode... XXX */
+ break;
+ case 1: /* CGA 40x25 */
+ /* switch to the 80x25 mode? XXX */
+ /* FALL THROUGH */
+ case 2: /* CGA 80x25 */
+ /* `crtc_type' has already been set... */
+ /* crtc_type = KD_CGA; */
+ break;
+ case 3: /* MDA */
+ /* `crtc_type' has already been set... */
+ /* crtc_type = KD_MONO; */
+ break;
+ }
+
+ /* is this a VGA or higher ? */
+ outb(crtc_addr, 7);
+ if (inb(crtc_addr) == 7) {
+
+ crtc_type = KD_VGA;
+ crtc_vga = TRUE;
+ read_vgaregs(vgaregs);
+
+ /* Get the BIOS video mode pointer */
+ segoff = *(u_long *)pa_to_va(0x4a8);
+ pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
+ if (ISMAPPED(pa, sizeof(u_long))) {
+ segoff = *(u_long *)pa_to_va(pa);
+ pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
+ if (ISMAPPED(pa, 64))
+ video_mode_ptr = (char *)pa_to_va(pa);
+ }
+ }
+
+ return TRUE;
+}
+
+/* probe the keyboard, return TRUE if found */
+static int
+sckbdprobe(int unit, int flags)
+{
int codeset;
int c = -1;
int m;
- sc_port = dev->id_iobase;
sc_kbdc = kbdc_open(sc_port);
if (!kbdc_lock(sc_kbdc, TRUE)) {
/* driver error? */
- printf("sc%d: unable to lock the controller.\n", dev->id_unit);
- return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+ printf("sc%d: unable to lock the controller.\n", unit);
+ return ((flags & DETECT_KBD) ? FALSE : TRUE);
}
/* discard anything left after UserConfig */
@@ -324,26 +438,35 @@ scprobe(struct isa_device *dev)
c = get_controller_command_byte(sc_kbdc);
if (c == -1) {
/* CONTROLLER ERROR */
- printf("sc%d: unable to get the current command byte value.\n",
- dev->id_unit);
+ printf("sc%d: unable to get the current command byte value.\n", unit);
goto fail;
}
if (bootverbose)
printf("sc%d: the current keyboard controller command byte %04x\n",
- dev->id_unit, c);
+ unit, c);
#if 0
/* override the keyboard lock switch */
c |= KBD_OVERRIDE_KBD_LOCK;
#endif
+ /*
+ * The keyboard may have been screwed up by the boot block.
+ * We may just be able to recover from error by testing the controller
+ * and the keyboard port. The controller command byte needs to be saved
+ * before this recovery operation, as some controllers seem to set
+ * the command byte to particular values.
+ */
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+
/* enable the keyboard port, but disable the keyboard intr. */
if (!set_controller_command_byte(sc_kbdc,
- KBD_KBD_CONTROL_BITS,
+ KBD_KBD_CONTROL_BITS,
KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT)) {
/* CONTROLLER ERROR
* there is very little we can do...
*/
- printf("sc%d: unable to set the command byte.\n", dev->id_unit);
+ printf("sc%d: unable to set the command byte.\n", unit);
goto fail;
}
@@ -354,7 +477,7 @@ scprobe(struct isa_device *dev)
* during the boot process.
*/
codeset = -1;
- if (dev->id_flags & XT_KEYBD)
+ if (flags & XT_KEYBD)
/* the user says there is a XT keyboard */
codeset = 1;
#ifdef DETECT_XT_KEYBOARD
@@ -365,7 +488,7 @@ scprobe(struct isa_device *dev)
codeset = read_kbd_data(sc_kbdc);
}
if (bootverbose)
- printf("sc%d: keyboard scancode set %d\n", dev->id_unit, codeset);
+ printf("sc%d: keyboard scancode set %d\n", unit, codeset);
#endif /* DETECT_XT_KEYBOARD */
/* reset keyboard hardware */
@@ -386,7 +509,7 @@ scprobe(struct isa_device *dev)
* the keyboard may still exist (see above).
*/
if (bootverbose)
- printf("sc%d: failed to reset the keyboard.\n", dev->id_unit);
+ printf("sc%d: failed to reset the keyboard.\n", unit);
goto fail;
}
@@ -405,7 +528,7 @@ scprobe(struct isa_device *dev)
* The XT kbd isn't usable unless the proper scan code set
* is selected.
*/
- printf("sc%d: unable to set the XT keyboard mode.\n", dev->id_unit);
+ printf("sc%d: unable to set the XT keyboard mode.\n", unit);
goto fail;
}
}
@@ -417,24 +540,23 @@ scprobe(struct isa_device *dev)
/* CONTROLLER ERROR
* This is serious; we are left with the disabled keyboard intr.
*/
- printf("sc%d: unable to enable the keyboard port and intr.\n",
- dev->id_unit);
+ printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
goto fail;
}
succeed:
kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
kbdc_lock(sc_kbdc, FALSE);
- return (IO_KBDSIZE);
+ return TRUE;
fail:
if (c != -1)
/* try to restore the command byte as before, if possible */
set_controller_command_byte(sc_kbdc, 0xff, c);
kbdc_set_device_mask(sc_kbdc,
- (dev->id_flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
+ (flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
kbdc_lock(sc_kbdc, FALSE);
- return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+ return FALSE;
}
#if NAPM > 0
@@ -508,16 +630,28 @@ scattach(struct isa_device *dev)
}
printf("sc%d: ", dev->id_unit);
- if (crtc_vga)
+ switch(crtc_type) {
+ case KD_VGA:
if (crtc_addr == MONO_BASE)
printf("VGA mono");
else
printf("VGA color");
- else
+ break;
+ case KD_EGA:
if (crtc_addr == MONO_BASE)
- printf("MDA/hercules");
+ printf("EGA mono");
else
- printf("CGA/EGA");
+ printf("EGA color");
+ break;
+ case KD_CGA:
+ printf("CGA");
+ break;
+ case KD_MONO:
+ case KD_HERCULES:
+ default:
+ printf("MDA/hercules");
+ break;
+ }
printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags);
#if NAPM > 0
@@ -745,13 +879,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
return 0;
case CONS_CURRENT: /* get current adapter type */
- if (crtc_vga)
- *(int*)data = KD_VGA;
- else
- if (crtc_addr == MONO_BASE)
- *(int*)data = KD_MONO;
- else
- *(int*)data = KD_CGA;
+ *(int *)data = crtc_type;
return 0;
case CONS_GET: /* get current video mode */
@@ -1465,6 +1593,11 @@ sccnprobe(struct consdev *cp)
return;
}
+ if (!scvidprobe(dvp->id_unit, dvp->id_flags)) {
+ cp->cn_pri = CN_DEAD;
+ return;
+ }
+
/* initialize required fields */
cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
cp->cn_pri = CN_INTERNAL;
@@ -2395,31 +2528,12 @@ outloop:
static void
scinit(void)
{
- u_short volatile *cp;
- u_short was;
u_int hw_cursor;
u_int i;
if (init_done != COLD)
return;
init_done = WARM;
- /*
- * Finish defaulting crtc variables for a mono screen. Crtat is a
- * bogus common variable so that it can be shared with pcvt, so it
- * can't be statically initialized. XXX.
- */
- Crtat = (u_short *)MONO_BUF;
- /*
- * If CGA memory seems to work, switch to color.
- */
- cp = (u_short *)CGA_BUF;
- was = *cp;
- *cp = (u_short) 0xA55A;
- if (*cp == 0xA55A) {
- Crtat = (u_short *)CGA_BUF;
- crtc_addr = COLOR_BASE;
- }
- *cp = was;
/*
* Ensure a zero start address. This is mainly to recover after
@@ -2451,25 +2565,7 @@ scinit(void)
outb(crtc_addr, 15);
outb(crtc_addr + 1, 0xff);
- /* is this a VGA or higher ? */
- outb(crtc_addr, 7);
- if (inb(crtc_addr) == 7) {
- u_long pa;
- u_long segoff;
-
- crtc_vga = TRUE;
- read_vgaregs(vgaregs);
-
- /* Get the BIOS video mode pointer */
- segoff = *(u_long *)pa_to_va(0x4a8);
- pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
- if (ISMAPPED(pa, sizeof(u_long))) {
- segoff = *(u_long *)pa_to_va(pa);
- pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
- if (ISMAPPED(pa, 64))
- video_mode_ptr = (char *)pa_to_va(pa);
- }
- }
+ /* set up the first console */
current_default = &user_default;
console[0] = &main_console;
init_scp(console[0]);
diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c
index 5d01115481b9..5df41907a37a 100644
--- a/sys/isa/syscons.c
+++ b/sys/isa/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.215 1997/05/07 20:02:38 peter Exp $
+ * $Id: syscons.c,v 1.216 1997/05/15 05:43:57 yokota Exp $
*/
#include "sc.h"
@@ -111,6 +111,7 @@ static char write_in_progress = FALSE;
static char blink_in_progress = FALSE;
static int blinkrate = 0;
u_int crtc_addr = MONO_BASE;
+ char crtc_type = KD_MONO;
char crtc_vga = FALSE;
static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0;
static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0;
@@ -171,10 +172,15 @@ static const int nsccons = MAXCONS+2;
+ (offset)) % (scp->history_size)))
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
+/* this should really be in `rtc.h' */
+#define RTC_EQUIPMENT 0x14
+
/* prototypes */
static int scattach(struct isa_device *dev);
static int scparam(struct tty *tp, struct termios *t);
static int scprobe(struct isa_device *dev);
+static int scvidprobe(int unit, int flags);
+static int sckbdprobe(int unit, int flags);
static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
static void scinit(void);
@@ -303,17 +309,125 @@ move_crsr(scr_stat *scp, int x, int y)
static int
scprobe(struct isa_device *dev)
{
+ if (!scvidprobe(dev->id_unit, dev->id_flags)) {
+ if (bootverbose)
+ printf("sc%d: no video adapter is found.\n", dev->id_unit);
+ return (0);
+ }
+
+ sc_port = dev->id_iobase;
+ if (sckbdprobe(dev->id_unit, dev->id_flags))
+ return (IO_KBDSIZE);
+ else
+ return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+}
+
+/* probe video adapters, return TRUE if found */
+static int
+scvidprobe(int unit, int flags)
+{
+ /*
+ * XXX don't try to `printf' anything here, the console may not have
+ * been configured yet.
+ */
+ u_short volatile *cp;
+ u_short was;
+ u_long pa;
+ u_long segoff;
+
+ /* do this test only once */
+ if (init_done != COLD)
+ return (Crtat != 0);
+
+ /*
+ * Finish defaulting crtc variables for a mono screen. Crtat is a
+ * bogus common variable so that it can be shared with pcvt, so it
+ * can't be statically initialized. XXX.
+ */
+ Crtat = (u_short *)MONO_BUF;
+ crtc_type = KD_MONO;
+ /* If CGA memory seems to work, switch to color. */
+ cp = (u_short *)CGA_BUF;
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp == 0xA55A) {
+ Crtat = (u_short *)CGA_BUF;
+ crtc_addr = COLOR_BASE;
+ crtc_type = KD_CGA;
+ } else {
+ cp = Crtat;
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp != 0xA55A) {
+ /* no screen at all, bail out */
+ Crtat = 0;
+ return FALSE;
+ }
+ }
+ *cp = was;
+
+ /*
+ * Check rtc and BIOS date area.
+ * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy
+ * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are
+ * zeros for EGA and VGA. However, the EGA/VGA BIOS will set
+ * these bits in BIOSDATA_EQUIPMENT according to the monitor
+ * type detected.
+ */
+ switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
+ case 0: /* EGA/VGA, or nothing */
+ crtc_type = KD_EGA;
+ /* the color adapter may be in the 40x25 mode... XXX */
+ break;
+ case 1: /* CGA 40x25 */
+ /* switch to the 80x25 mode? XXX */
+ /* FALL THROUGH */
+ case 2: /* CGA 80x25 */
+ /* `crtc_type' has already been set... */
+ /* crtc_type = KD_CGA; */
+ break;
+ case 3: /* MDA */
+ /* `crtc_type' has already been set... */
+ /* crtc_type = KD_MONO; */
+ break;
+ }
+
+ /* is this a VGA or higher ? */
+ outb(crtc_addr, 7);
+ if (inb(crtc_addr) == 7) {
+
+ crtc_type = KD_VGA;
+ crtc_vga = TRUE;
+ read_vgaregs(vgaregs);
+
+ /* Get the BIOS video mode pointer */
+ segoff = *(u_long *)pa_to_va(0x4a8);
+ pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
+ if (ISMAPPED(pa, sizeof(u_long))) {
+ segoff = *(u_long *)pa_to_va(pa);
+ pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
+ if (ISMAPPED(pa, 64))
+ video_mode_ptr = (char *)pa_to_va(pa);
+ }
+ }
+
+ return TRUE;
+}
+
+/* probe the keyboard, return TRUE if found */
+static int
+sckbdprobe(int unit, int flags)
+{
int codeset;
int c = -1;
int m;
- sc_port = dev->id_iobase;
sc_kbdc = kbdc_open(sc_port);
if (!kbdc_lock(sc_kbdc, TRUE)) {
/* driver error? */
- printf("sc%d: unable to lock the controller.\n", dev->id_unit);
- return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+ printf("sc%d: unable to lock the controller.\n", unit);
+ return ((flags & DETECT_KBD) ? FALSE : TRUE);
}
/* discard anything left after UserConfig */
@@ -324,26 +438,35 @@ scprobe(struct isa_device *dev)
c = get_controller_command_byte(sc_kbdc);
if (c == -1) {
/* CONTROLLER ERROR */
- printf("sc%d: unable to get the current command byte value.\n",
- dev->id_unit);
+ printf("sc%d: unable to get the current command byte value.\n", unit);
goto fail;
}
if (bootverbose)
printf("sc%d: the current keyboard controller command byte %04x\n",
- dev->id_unit, c);
+ unit, c);
#if 0
/* override the keyboard lock switch */
c |= KBD_OVERRIDE_KBD_LOCK;
#endif
+ /*
+ * The keyboard may have been screwed up by the boot block.
+ * We may just be able to recover from error by testing the controller
+ * and the keyboard port. The controller command byte needs to be saved
+ * before this recovery operation, as some controllers seem to set
+ * the command byte to particular values.
+ */
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+
/* enable the keyboard port, but disable the keyboard intr. */
if (!set_controller_command_byte(sc_kbdc,
- KBD_KBD_CONTROL_BITS,
+ KBD_KBD_CONTROL_BITS,
KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT)) {
/* CONTROLLER ERROR
* there is very little we can do...
*/
- printf("sc%d: unable to set the command byte.\n", dev->id_unit);
+ printf("sc%d: unable to set the command byte.\n", unit);
goto fail;
}
@@ -354,7 +477,7 @@ scprobe(struct isa_device *dev)
* during the boot process.
*/
codeset = -1;
- if (dev->id_flags & XT_KEYBD)
+ if (flags & XT_KEYBD)
/* the user says there is a XT keyboard */
codeset = 1;
#ifdef DETECT_XT_KEYBOARD
@@ -365,7 +488,7 @@ scprobe(struct isa_device *dev)
codeset = read_kbd_data(sc_kbdc);
}
if (bootverbose)
- printf("sc%d: keyboard scancode set %d\n", dev->id_unit, codeset);
+ printf("sc%d: keyboard scancode set %d\n", unit, codeset);
#endif /* DETECT_XT_KEYBOARD */
/* reset keyboard hardware */
@@ -386,7 +509,7 @@ scprobe(struct isa_device *dev)
* the keyboard may still exist (see above).
*/
if (bootverbose)
- printf("sc%d: failed to reset the keyboard.\n", dev->id_unit);
+ printf("sc%d: failed to reset the keyboard.\n", unit);
goto fail;
}
@@ -405,7 +528,7 @@ scprobe(struct isa_device *dev)
* The XT kbd isn't usable unless the proper scan code set
* is selected.
*/
- printf("sc%d: unable to set the XT keyboard mode.\n", dev->id_unit);
+ printf("sc%d: unable to set the XT keyboard mode.\n", unit);
goto fail;
}
}
@@ -417,24 +540,23 @@ scprobe(struct isa_device *dev)
/* CONTROLLER ERROR
* This is serious; we are left with the disabled keyboard intr.
*/
- printf("sc%d: unable to enable the keyboard port and intr.\n",
- dev->id_unit);
+ printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
goto fail;
}
succeed:
kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
kbdc_lock(sc_kbdc, FALSE);
- return (IO_KBDSIZE);
+ return TRUE;
fail:
if (c != -1)
/* try to restore the command byte as before, if possible */
set_controller_command_byte(sc_kbdc, 0xff, c);
kbdc_set_device_mask(sc_kbdc,
- (dev->id_flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
+ (flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
kbdc_lock(sc_kbdc, FALSE);
- return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
+ return FALSE;
}
#if NAPM > 0
@@ -508,16 +630,28 @@ scattach(struct isa_device *dev)
}
printf("sc%d: ", dev->id_unit);
- if (crtc_vga)
+ switch(crtc_type) {
+ case KD_VGA:
if (crtc_addr == MONO_BASE)
printf("VGA mono");
else
printf("VGA color");
- else
+ break;
+ case KD_EGA:
if (crtc_addr == MONO_BASE)
- printf("MDA/hercules");
+ printf("EGA mono");
else
- printf("CGA/EGA");
+ printf("EGA color");
+ break;
+ case KD_CGA:
+ printf("CGA");
+ break;
+ case KD_MONO:
+ case KD_HERCULES:
+ default:
+ printf("MDA/hercules");
+ break;
+ }
printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags);
#if NAPM > 0
@@ -745,13 +879,7 @@ scioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
return 0;
case CONS_CURRENT: /* get current adapter type */
- if (crtc_vga)
- *(int*)data = KD_VGA;
- else
- if (crtc_addr == MONO_BASE)
- *(int*)data = KD_MONO;
- else
- *(int*)data = KD_CGA;
+ *(int *)data = crtc_type;
return 0;
case CONS_GET: /* get current video mode */
@@ -1465,6 +1593,11 @@ sccnprobe(struct consdev *cp)
return;
}
+ if (!scvidprobe(dvp->id_unit, dvp->id_flags)) {
+ cp->cn_pri = CN_DEAD;
+ return;
+ }
+
/* initialize required fields */
cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
cp->cn_pri = CN_INTERNAL;
@@ -2395,31 +2528,12 @@ outloop:
static void
scinit(void)
{
- u_short volatile *cp;
- u_short was;
u_int hw_cursor;
u_int i;
if (init_done != COLD)
return;
init_done = WARM;
- /*
- * Finish defaulting crtc variables for a mono screen. Crtat is a
- * bogus common variable so that it can be shared with pcvt, so it
- * can't be statically initialized. XXX.
- */
- Crtat = (u_short *)MONO_BUF;
- /*
- * If CGA memory seems to work, switch to color.
- */
- cp = (u_short *)CGA_BUF;
- was = *cp;
- *cp = (u_short) 0xA55A;
- if (*cp == 0xA55A) {
- Crtat = (u_short *)CGA_BUF;
- crtc_addr = COLOR_BASE;
- }
- *cp = was;
/*
* Ensure a zero start address. This is mainly to recover after
@@ -2451,25 +2565,7 @@ scinit(void)
outb(crtc_addr, 15);
outb(crtc_addr + 1, 0xff);
- /* is this a VGA or higher ? */
- outb(crtc_addr, 7);
- if (inb(crtc_addr) == 7) {
- u_long pa;
- u_long segoff;
-
- crtc_vga = TRUE;
- read_vgaregs(vgaregs);
-
- /* Get the BIOS video mode pointer */
- segoff = *(u_long *)pa_to_va(0x4a8);
- pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
- if (ISMAPPED(pa, sizeof(u_long))) {
- segoff = *(u_long *)pa_to_va(pa);
- pa = (((segoff & 0xffff0000) >> 12) + (segoff & 0xffff));
- if (ISMAPPED(pa, 64))
- video_mode_ptr = (char *)pa_to_va(pa);
- }
- }
+ /* set up the first console */
current_default = &user_default;
console[0] = &main_console;
init_scp(console[0]);