DragonFly on Intel Mac?

YONETANI Tomokazu qhwt+dfly at les.ath.cx
Sat Mar 10 22:53:17 PST 2007


On Tue, Mar 06, 2007 at 08:08:31AM -0800, Matthew Dillon wrote:
>     There's something going on with the stray irq printf() itself
>     possibly being the cause of the double fault.  I think the printf()
>     in that situation (interrupting random kernel code without MP lock
>     controls) is not safe.
> 
>     Except for the interrupt disablement and reenablement bits, I like
>     the patch.  I don't think those bits are necessary.  

Ripped the interrupt disablement and reenablement bit and it works.
Also the previous patch missed changes to dev/misc/kbd .

>     It may also be a good idea to put a DELAY() in the C code loop instead
>     of relying on ISA bus timing (which won't actually be ISA bus timing
>     because the ISA bus is faked these days).  I'm not sure what 
>     the best solution would be for the assembly.  It might not be a big 
>     deal but it could save us headaches later on.

The commit log for original patch doesn't seem to be very determined about
the amount of time to wait.  Inserting DELAY(16) can gurantee to wait
at least for one second before giving up.

On Tue, Mar 06, 2007 at 07:11:48PM -0500, Justin C. Sherrill wrote:
> On Tue, March 6, 2007 8:41 am, YONETANI Tomokazu wrote:
> 
> >  With this patch, it does boot past the boot loader, but it ends up
> > in double fault after many lines of 'sched_ithd: stray interrupt 7'.
> > Also I need to disable acpi driver because it fills the screen with
> > garbage and I can't see anything in the boot log.  I tested cdboot
> > and the kernel on other PCs and had no problem.  So it's probably
> > safe to commit.
> 
> If you have a disk image to try out, I can give it a whirl on my MacBook Pro.

You mean the hard disk image?  Maybe you can install it to a BootCamp
partition(mine appears as /dev/disk0s3) using `dd' command from Mac OS X,
but I haven't tried it yet.  On FreeBSD, the disk appears to be ad5s3, but
I could use boot0cfg, so I imagine just installing the slice image doesn't
make it bootable.  I need to investigate on this later.

Cheers.
Index: boot/i386/cdboot/cdboot.S
===================================================================
RCS file: /home/source/dragonfly/cvs/src/sys/boot/i386/cdboot/cdboot.S,v
retrieving revision 1.7
diff -u -p -r1.7 cdboot.S
--- boot/i386/cdboot/cdboot.S	13 Jan 2006 19:41:50 -0000	1.7
+++ boot/i386/cdboot/cdboot.S	27 Feb 2007 23:57:54 -0000
@@ -461,10 +461,17 @@ twiddle:	push %ax			# Save
 		ret
 
 		/*
-		 * Enable A20
+		 * Enable A20. Put upper limit on amount of time we wait for the
+		 * keyboard controller to get ready (65K x ISA access time). If
+		 * we wait more than that amount it's likely that the hardware
+		 * is legacy-free and simply doesn't have keyboard controller
+		 * and don't need enabling A20 at all.
 		 */
 seta20: 	cli				# Disable interrupts
-seta20.1:	in $0x64,%al			# Get status
+		xor %cx,%cx			# Clear
+seta20.1:	inc %cx				# Increment, overflow?
+		jz seta20.3			# Yes
+		in $0x64,%al			# Get status
 		test $0x2,%al			# Busy?
 		jnz seta20.1			# Yes
 		mov $0xd1,%al			# Command: Write
@@ -474,7 +481,7 @@ seta20.2:	in $0x64,%al			# Get status
 		jnz seta20.2			# Yes
 		mov $0xdf,%al			# Enable
 		out %al,$0x60			#  A20
-		sti				# Enable interrupts
+seta20.3:	sti				# Enable interrupts
 		ret				# To caller
 
 		/*
Index: boot/i386/pxeldr/pxeldr.S
===================================================================
RCS file: /home/source/dragonfly/cvs/src/sys/boot/i386/pxeldr/pxeldr.S,v
retrieving revision 1.4
diff -u -p -r1.4 pxeldr.S
--- boot/i386/pxeldr/pxeldr.S	18 Jul 2004 23:40:09 -0000	1.4
+++ boot/i386/pxeldr/pxeldr.S	28 Feb 2007 14:26:15 -0000
@@ -234,10 +234,17 @@ putc:		movw $0x7,%bx			# attribute for o
 		jmp putstr			# keep looping
 
 		/*
-		 * Enable A20
+		 * Enable A20. Put upper limit on amount of time we wait for the
+		 * keyboard controller to get ready (65K x ISA access time). If
+		 * we wait more than that amount it's likely that the hardware
+		 * is legacy-free and simply doesn't have keyboard controller
+		 * and don't need enabling A20 at all.
 		 */
 seta20: 	cli				# Disable interrupts
-seta20.1:	inb $0x64,%al			# Get status
+		xor %cx,%cx			# Clear
+seta20.1:	inc %cx				# Increment, overflow?
+		jz seta20.3			# Yes
+		inb $0x64,%al			# Get status
 		testb $0x2,%al			# Busy?
 		jnz seta20.1			# Yes
 		movb $0xd1,%al			# Command: Write
@@ -247,7 +254,7 @@ seta20.2:	inb $0x64,%al			# Get status
 		jnz seta20.2			# Yes
 		movb $0xdf,%al			# Enable
 		outb %al,$0x60			#  A20
-		sti				# Enable interrupts
+seta20.3:	sti				# Enable interrupts
 		retw				# To caller
 
 		/*
Index: dev/misc/atkbdc_layer/atkbdc_isa.c
===================================================================
RCS file: /home/source/dragonfly/cvs/src/sys/dev/misc/atkbdc_layer/atkbdc_isa.c,v
retrieving revision 1.7
diff -u -p -r1.7 atkbdc_isa.c
--- dev/misc/atkbdc_layer/atkbdc_isa.c	22 Dec 2006 23:26:17 -0000	1.7
+++ dev/misc/atkbdc_layer/atkbdc_isa.c	7 Mar 2007 13:57:22 -0000
@@ -101,6 +101,11 @@ atkbdc_probe(device_t dev)
 	struct resource	*port1;
 	int		error;
 	int		rid;
+#if defined(__i386__)
+	bus_space_tag_t	tag;
+	bus_space_handle_t ioh1;
+	volatile int	i;
+#endif
 
 	/* check PnP IDs */
 	if (ISA_PNP_PROBE(device_get_parent(dev), dev, atkbdc_ids) == ENXIO)
@@ -126,6 +131,28 @@ atkbdc_probe(device_t dev)
 		return ENXIO;
 	}
 
+#if defined(__i386__)
+	/*
+	 * Check if we really have AT keyboard controller. Poll status
+	 * register until we get "all clear" indication. If no such
+	 * indication comes, it probably means that there is no AT
+	 * keyboard controller present. Give up in such case. Check relies
+	 * on the fact that reading from non-existing in/out port returns
+	 * 0xff on i386. May or may not be true on other platforms.
+	 */
+	tag = rman_get_bustag(port0);
+	ioh1 = rman_get_bushandle(port1);
+	for (i = 0; i != 65535; i++) {
+		if ((bus_space_read_1(tag, ioh1, 0) & 0x2) == 0)
+			break;
+	}
+	if (i == 65535) {
+		bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
+		bus_release_resource(dev, SYS_RES_IOPORT, 1, port1);
+		return ENXIO;
+	}
+#endif
+
 	error = atkbdc_probe_unit(device_get_unit(dev), port0, port1);
 
 	bus_release_resource(dev, SYS_RES_IOPORT, 0, port0);
Index: dev/misc/kbd/atkbd.c
===================================================================
RCS file: /home/source/dragonfly/cvs/src/sys/dev/misc/kbd/atkbd.c,v
retrieving revision 1.13
diff -u -p -r1.13 atkbd.c
--- dev/misc/kbd/atkbd.c	22 Dec 2006 23:26:17 -0000	1.13
+++ dev/misc/kbd/atkbd.c	28 Feb 2007 12:22:00 -0000
@@ -270,12 +270,12 @@ atkbd_configure(int flags)
 	int arg[2];
 	int i;
 
-	/* probe the keyboard controller */
-	atkbdc_configure();
-
-	/* if the driver is disabled, unregister the keyboard if any */
-	if ((resource_int_value("atkbd", ATKBD_DEFAULT, "disabled", &i) == 0)
-	    && i != 0) {
+	/*
+	 * Probe the keyboard controller, if not present or if the driver
+	 * is disabled, unregister the keyboard if any.
+	 */
+	if (atkbdc_configure() != 0 ||
+	    resource_disabled("atkbd", ATKBD_DEFAULT)) {
 		i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT);
 		if (i >= 0) {
 			kbd = kbd_get_keyboard(i);
Index: dev/misc/kbd/atkbdc.c
===================================================================
RCS file: /home/source/dragonfly/cvs/src/sys/dev/misc/kbd/atkbdc.c,v
retrieving revision 1.9
diff -u -p -r1.9 atkbdc.c
--- dev/misc/kbd/atkbdc.c	15 Jan 2007 00:11:36 -0000	1.9
+++ dev/misc/kbd/atkbdc.c	10 Mar 2007 10:54:08 -0000
@@ -143,6 +143,9 @@ atkbdc_configure(void)
 	bus_space_handle_t h1;
 	int port0;
 	int port1;
+#if defined(__i386__)
+	volatile int i;
+#endif
 
 	port0 = IO_KBD;
 	resource_int_value("atkbdc", 0, "port", &port0);
@@ -163,6 +166,24 @@ atkbdc_configure(void)
 	h0 = (bus_space_handle_t)port0;
 	h1 = (bus_space_handle_t)port1;
 #endif
+
+#if defined(__i386__)
+	/*
+	 * Check if we really have AT keyboard controller. Poll status
+	 * register until we get "all clear" indication. If no such
+	 * indication comes, it probably means that there is no AT
+	 * keyboard controller present. Give up in such case. Check relies
+	 * on the fact that reading from non-existing in/out port returns
+	 * 0xff on i386. May or may not be true on other platforms.
+	 */
+	for (i = 0; i != 65535; i++) {
+		if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0)
+			break;
+	}
+	if (i == 65535)
+                return ENXIO;
+#endif
+
 	return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
 }
 




More information about the Submit mailing list