Subject: Re: Support for PS/2 esdi disks in bootblocks
To: Rafal Boni <rafal@mediaone.net>
From: Jaromír <jdolecek@netbsd.org>
List: port-i386
Date: 05/07/2001 17:28:55
--ELM989249335-326-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=US-ASCII
Rafal Boni wrote:
> That's great, in that case we can DTRT and not force non-MCA ESDI disks
> to in effect be obsoleted.
Okay, I've implemented an easier way to do it - if the machine is a
PS/2, DTYPE_ESDI disks are treated as ed(4), otherwise they
fallback to wd(4). I've also changed gateA20() to check
the machine model and use the L40 initialize code if appropriate
(so the thing is runtime option, rather than compile time).
The size different between "old" and "new" biosboot[_com0].sym is like
280 bytes.
However, I recognize this way is not quite right. It's my understanding
that there are some MCA wd1000/wd2000 controller cards and hence
it IS probably possible to have a wd(4)-type disk in an PS/2 too.
I don't know if those are bootable, though.
Since it's impossible to say until I'd have such machine/card available,
I think it's probably okay to get away with the above check only.
It would be possible to write something which would check if
ed(4) is actually installed and it's geometry matches the bios disk,
but that looks like unnecessary bloat in this case.
Jaromir
--
Jaromir Dolecek <jdolecek@NetBSD.org> http://www.ics.muni.cz/~dolecek/
NetBSD - just plain best OS! -=*=- Got spare MCA cards or docs? Hand me them!
--ELM989249335-326-0_
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=ISO-8859-2
Content-Disposition: attachment; filename=biosboot.ps2.diff
Index: biosboot/Makefile
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/stand/biosboot/Makefile,v
retrieving revision 1.35
diff -u -p -r1.35 Makefile
--- biosboot/Makefile 2001/05/02 13:43:11 1.35
+++ biosboot/Makefile 2001/05/07 15:25:04
@@ -15,7 +15,7 @@ SRCS= main.c devopen.c conf.c exec.c
CLEANFILES+= ${BSSTART}
-CPPFLAGS+= -DCOMPAT_OLDBOOT -DCOMPAT_386BSD_MBRPART
+CPPFLAGS+= -DCOMPAT_OLDBOOT -DCOMPAT_386BSD_MBRPART -DSUPPORT_PS2
.if (${BASE} == "biosboot")
# Various serial line configurations
Index: biosboot/devopen.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/stand/biosboot/devopen.c,v
retrieving revision 1.9
diff -u -p -r1.9 devopen.c
--- biosboot/devopen.c 1999/10/28 05:20:05 1.9
+++ biosboot/devopen.c 2001/05/07 15:25:04
@@ -46,6 +46,9 @@
#ifdef _STANDALONE
#include <bootinfo.h>
#endif
+#ifdef SUPPORT_PS2
+#include <biosmca.h>
+#endif
extern int parsebootfile __P((const char *, char**, char**, unsigned int*,
unsigned int*, const char**));
@@ -54,7 +57,7 @@ static int dev2bios __P((char *, unsigne
static struct {
char *name;
- int biosdev;
+ u_int8_t biosdev;
} biosdevtab[] = {
{
"fd", 0
@@ -68,8 +71,13 @@ static struct {
},
{
"sd", 0x80
+ },
+#ifdef SUPPORT_PS2
+ {
+ "ed", 0x80
}
-#endif
+#endif /* SUPPORT_PS2 */
+#endif /* COMPAT_OLDBOOT */
};
#define NUMBIOSDEVS (sizeof(biosdevtab) / sizeof(biosdevtab[0]))
@@ -98,22 +106,30 @@ bios2dev(biosdev, devname, unit)
char **devname;
unsigned int *unit;
{
+ u_int8_t devidx;
+
if (biosdev & 0x80) {
#if defined(COMPAT_OLDBOOT) && defined(_STANDALONE)
extern struct disklabel disklabel;
- if(disklabel.d_magic == DISKMAGIC) {
- if(disklabel.d_type == DTYPE_SCSI)
- *devname = biosdevtab[3].name;
+ if (disklabel.d_magic == DISKMAGIC) {
+ if (disklabel.d_type == DTYPE_SCSI)
+ devidx = 3;
+#ifdef SUPPORT_PS2
+ else if (disklabel.d_type == DTYPE_ESDI
+ && biosmca_ps2model)
+ devidx = 4;
+#endif
else
- *devname = biosdevtab[2].name;
+ devidx = 2;
} else
#endif
/* call it "hd", we don't know better */
- *devname = biosdevtab[1].name;
+ devidx = 1;
} else
- *devname = biosdevtab[0].name;
+ devidx = 0;
+ *devname = biosdevtab[devidx].name;
*unit = biosdev & 0x7f;
return (0);
Index: biosboot/main.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/stand/biosboot/main.c,v
retrieving revision 1.24
diff -u -p -r1.24 main.c
--- biosboot/main.c 2000/09/24 18:28:21 1.24
+++ biosboot/main.c 2001/05/07 15:25:04
@@ -47,6 +47,10 @@
#include <libi386.h>
#include "devopen.h"
+#ifdef SUPPORT_PS2
+#include <biosmca.h>
+#endif
+
int errno;
extern int boot_biosdev;
@@ -232,6 +236,10 @@ main()
initio(SUPPORT_SERIAL);
#else
initio(CONSDEV_PC);
+#endif
+
+#ifdef SUPPORT_PS2
+ biosmca();
#endif
gateA20();
Index: biosboot/version
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/stand/biosboot/version,v
retrieving revision 1.9
diff -u -p -r1.9 version
--- biosboot/version 2000/09/24 12:32:35 1.9
+++ biosboot/version 2001/05/07 15:25:04
@@ -15,3 +15,6 @@ is taken as the current.
2.6: Support ELF boot.
2.7: Support on-the-fly switching of console devices.
2.8: Support verbose/quiet boot.
+2.9: Recognize ESDI disks and identify them as ed(4)
+ Recognize PS/2 L40 at runtime and use appropriate gate A20
+ initialization (rather than using a compile flag)
Index: lib/Makefile
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/stand/lib/Makefile,v
retrieving revision 1.17
diff -u -p -r1.17 Makefile
--- lib/Makefile 2000/09/24 18:13:54 1.17
+++ lib/Makefile 2001/05/07 15:25:04
@@ -9,6 +9,7 @@ MKPROFILE=no
I386_INCLUDE_DISK?= yes
I386_INCLUDE_DOS?= no
I386_INCLUDE_BUS?= no
+I386_INCLUDE_PS2?= yes
CPPFLAGS= -I$S/lib/libsa ${I386CPPFLAGS} ${I386MISCCPPFLAGS}
#CPPFLAGS+= -DDISK_DEBUG
@@ -32,6 +33,9 @@ SRCS+= diskbuf.c
.endif
.if (${I386_INCLUDE_BUS} == "yes")
SRCS+= biospci.c bios_pci.S isapnp.c isadma.c
+.endif
+.if (${I386_INCLUDE_PS2} == "yes")
+SRCS+= biosmca.S
.endif
.include <bsd.lib.mk>
Index: lib/biosmca.S
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/stand/lib/biosmca.S,v
retrieving revision 1.1
diff -u -p -r1.1 biosmca.S
--- lib/biosmca.S 2001/05/02 13:41:07 1.1
+++ lib/biosmca.S 2001/05/07 15:25:04
@@ -58,13 +58,18 @@ WITH THE USE OR PERFORMANCE OF THIS SOFT
#define addr32 .byte 0x67
#define data32 .byte 0x66
+ .data
+ .globl _C_LABEL(biosmca_ps2model)
+_C_LABEL(biosmca_ps2model): .long 0
+
+ .text
/*
# BIOS call "INT 0x15 Function 0xc0" to read extended sys config info on PS/2
-# Return:
-# %ah = 0x0 on success; err code on failure
-# %es:%bx = segment:offset of ROM address of sys config
-# Called like
-# biosmca(&model, &features)
+# Return: no return value
+#
+# This function initializes biosmca_ps2model with model number as
+# identified by BIOS, if the machine is a PS/2 box (i.e. has MCA bus
+# instead of ISA).
*/
ENTRY(biosmca)
pushl %ebp
@@ -74,41 +79,41 @@ ENTRY(biosmca)
push %edx
push %esi
push %edi
+ push %eax
call _C_LABEL(prot_to_real) # enter real mode
+ # zero %cx
+ data32
+ xorl %cx, %cx
+
data32
- movl $0xa0, %ax # set table length to 0
+ xorl %ax, %ax
movb $0xc0, %ah # subfunction
int $0x15
- jc err
+ jc back
+ # check feature byte 1 if MCA bus present and replaces ISA
addr32
- movl %es, %cx
+ movb %es:5(%ebx), %ax
+ andw $0x02, %ax # bit 1 set means MCA instead of ISA
+ cmpw $0x02, %ax # see also arch/i386/mca/mca_machdep.c
+ jne back
+
+ # save model and submodel bytes to %cx
addr32
- movl %bx, %dx
- data32
- movl %ax, %bx
- jmp back
-
-err:
- data32
- movb $0, %bx
+ movb %es:2(%ebx), %ch # model (1 byte)
+ addr32
+ movb %es:3(%ebx), %cl # submodel (1 byte)
back:
data32
call _C_LABEL(real_to_prot) # back to protected mode
- xorl %eax, %eax
- movw %bx, %ax # return value in %ax
-
# save model
- movl 28(%esp), %ebx
- movl %ecx, 0(%ebx)
- # save bios rev & features
- movl 32(%esp), %ebx
- movl %edx, 0(%ebx)
+ movl %ecx, _C_LABEL(biosmca_ps2model)
+ pop %eax
pop %edi
pop %esi
pop %edx
Index: lib/exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/stand/lib/exec.c,v
retrieving revision 1.15
diff -u -p -r1.15 exec.c
--- lib/exec.c 2000/02/22 07:45:04 1.15
+++ lib/exec.c 2001/05/07 15:25:04
@@ -58,6 +58,9 @@
#include "loadfile.h"
#include "libi386.h"
#include "bootinfo.h"
+#ifdef SUPPORT_PS2
+#include "biosmca.h"
+#endif
#ifdef COMPAT_OLDBOOT
static int dev2major __P((char *, int *));
@@ -67,13 +70,23 @@ dev2major(devname, major)
char *devname;
int *major;
{
- static char *devices[] = {"wd", "", "fd", "", "sd"};
-#define NUMDEVICES (sizeof(devices)/sizeof(char *))
+ static const struct {
+ const char *name;
+ int maj;
+ } devices[] = {
+ { "wd", 0 },
+ { "fd", 2 },
+ { "sd", 4 },
+#ifdef SUPPORT_PS2
+ { "ed", 20 },
+#endif
+ };
+#define NUMDEVICES (sizeof(devices)/sizeof(devices[0]))
int i;
for (i = 0; i < NUMDEVICES; i++)
- if (!strcmp(devname, devices[i])) {
- *major = i;
+ if (!strcmp(devname, devices[i].name)) {
+ *major = devices[i].maj;
return (0);
}
return (-1);
@@ -166,10 +179,21 @@ exec_netbsd(file, loadaddr, boothowto)
/* generic BIOS disk, have to guess type */
struct open_file *f = &files[fd]; /* XXX */
- if (biosdisk_gettype(f) == DTYPE_SCSI)
+ switch (biosdisk_gettype(f)) {
+ case DTYPE_SCSI:
devname = "sd";
- else
+ break;
+#ifdef SUPPORT_PS2
+ case DTYPE_ESDI:
+ if (biosmca_ps2model) {
+ devname = "ed";
+ break;
+ }
+#endif
+ default:
devname = "wd";
+ break;
+ }
/*
* The old boot block performed the following
Index: lib/gatea20.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/stand/lib/gatea20.c,v
retrieving revision 1.3
diff -u -p -r1.3 gatea20.c
--- lib/gatea20.c 2000/05/11 16:11:54 1.3
+++ lib/gatea20.c 2001/05/07 15:25:04
@@ -8,6 +8,7 @@
#include <lib/libsa/stand.h>
#include "libi386.h"
+#include "biosmca.h"
#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
#define K_STATUS 0x64 /* keyboard status */
@@ -27,15 +28,19 @@
/*
* Gate A20 for high memory
*/
-#ifndef IBM_L40
static unsigned char x_20 = KB_A20;
-#endif
void gateA20()
{
__asm("pushfl ; cli");
-#ifdef IBM_L40
- outb(0x92, 0x2);
-#else /* !IBM_L40 */
+#ifdef SUPPORT_PS2
+ /*
+ * Check if the machine is PS/2 L40 via biosmca_model, which is
+ * initialized before gateA20() is called.
+ */
+ if (biosmca_ps2model == 0xf82)
+ outb(0x92, 0x2);
+ else {
+#endif
while (inb(K_STATUS) & K_IBUF_FUL);
while (inb(K_STATUS) & K_OBUF_FUL)
(void)inb(K_RDWR);
@@ -46,6 +51,8 @@ void gateA20()
outb(K_RDWR, x_20);
delay(100);
while (inb(K_STATUS) & K_IBUF_FUL);
-#endif /* IBM_L40 */
+#ifdef SUPPORT_PS2
+ }
+#endif
__asm("popfl");
}
--ELM989249335-326-0_--