[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] [PATCH] Fix 6888x detection + SFP004 support



Hi,

following the discussion from February on this and Hatari lists regarding the FPU detection I set a goal to fix this but I needed physical access to my MegaSTE + 68881 so it took some time.

The basic problem was that FreeMiNT detection code has been checking for revision numbers and not stack frame sizes, what is the recommended procedure by Motorola.

This patch's changes:
- FPU detection code algorithm improvement
- the check in the sig handler, it has been working only by chance
- adds support for SFP-004 boards, i.e. my MegaSTE now correctly reports not only SFP-004 but also what kind of FPU is installed

I'm not sure how context switching applies to SFP-004? I.e. whether we're supposed to save context here, too? I'd say we are but who knows. Anyway, it's quite a complex change and it requires two SFP-compatible/aware programs running at the same time under FreeMiNT to make a collision...

Just for fun I tried some sysinfo tools, whether they notice the fixed/improved _FPU cookie:

- Sysinfo 5.02 is confused by 0x00050000, while it reports "MC68881/SFP004" in the cookie list, it goes from "68000/68881" to "68000/???" in the machine info

- SYSINFO 8.34 does notice, it goes from "SFP004 or compatible" to "68881 + SFP004"

So I'd say it's good to go. I know it's only a minor improvement and very few people will appreciate it (=me ;-)) but it's the right thing to do! :)

--
MiKRO / Mystic Bytes
http://mikro.atari.org
Index: arch/detect.S
===================================================================
RCS file: /mint/freemint/sys/arch/detect.S,v
retrieving revision 1.15
diff -u -r1.15 detect.S
--- arch/detect.S	12 Jan 2013 10:04:58 -0000	1.15
+++ arch/detect.S	30 May 2015 16:40:46 -0000
@@ -301,18 +301,20 @@
 // FPU type detection, experimental (draco@atari.org).
 //
 // This can only detect the hardware FPU, any software emulation
-// will be ignored.
-//
-// NOTICE: the _FPU cookie value for 68060 is not defined by Atari!
-//         *** How does it look like on a Hades060? ***
+// will be ignored (a non-zero low word indicates the presence of software
+// floating point support; no specific values have yet been assigned).
 //
 // Return value is cookie value for _FPU slot or a zero if no FPU
 // is present:
 //
 // 0x00000000, no FPU
-// 0x00020000, 68881 or 68882
-// 0x00040000, 68881 for sure
-// 0x00060000, 68882 for sure
+// 0x00010000, SFP-004 or compatible FPU-card (6888x as a peripheral component) [unused]
+// 0x00020000, 68881 or 68882 [unused]
+// 0x00030000, 68881 or 68882 and SFP-004 [unused]
+// 0x00040000, 68881
+// 0x00050000, 68881 and SFP-004
+// 0x00060000, 68882
+// 0x00070000, 68882 and SFP-004
 // 0x00080000, 68040 internal FPU
 // 0x00100000, 68060 internal FPU
 //
@@ -322,11 +324,8 @@
 //   in coprocessor mode. If the CPU is >= 68020, no FPU is assumed.
 // - if FNOP doesn't take an exception, an FPU attached in coprocessor mode
 //   is present. Then if 68040 or 68060 CPU was detected previously, an appropriate
-//   FPU type is assumed. Otherwise the stackframe is checked for magic value
-//   indicating 68882 and if it is different, a 68881 is assumed.
-//
-// I am very interested if this will really work on everything =)
-// On a 68030/68882 tandem it does.
+//   FPU type is assumed. Otherwise the stackframe is checked for stack frame size
+//   indicating 68881 and if it is different, a 68882 is assumed.
 
 	.globl	_detect_fpu
 	.globl	_mcpu
@@ -374,14 +373,27 @@
 	moveq	#0x08,d0	// if not 060, maybe a 040 (cookie 0x00080000)
 	cmpi.w	#40,d1
 	beq.s	fexit
-	moveq	#0x06,d0	// if neither, so maybe a 68882 (cookie 0x00060000)
-	move.b	(sp)+,d1
-	cmpi.b	#0x1f,d1
-	beq.s	fexit
-	moveq	#0x04,d0	// must be 68881
+	clr.l	d0
+x688x:	move.b	1(sp),d1	// if neither, maybe a 68881 or 68882
+	cmpi.b	#0x18,d1
+	bne.s	no6881
+	ori.w	#0x04,d0	// 68881 (cookie 0x00040000)
+	bne.s	fexit
+no6881:	ori.w	#0x06,d0	// must be 68882 (cookie 0x00060000)
 	bra.s	fexit
-sfp:	tst.w	(0xfa40).w	// CIR
+
+sfp:	move.w	(0xfa44).w,d0	// read the save register
+	move.w	d0,d1
+	andi.w	#0xff00,d1	// isolate the format word
+	beq.s	sfp_store	// if null idle, store the format word
+	cmpi.w	#0x0100,d1	// if the coprocessor busy
+	beq.s	sfp		// keep checking until CP is finished processing
+sfp_store:
+	swap	d0		// place the format word in the upper 16 bits
+	move.l	d0,-(sp)	// store format word on the stack
 	moveq	#0x01,d0	// memory mapped FPU
+	bra.s	x688x
+
 fexit:	move.l	a1,(0x2c).w	// restore Line-F
 	move.l	a2,(0x08).w
 	move.l	a0,sp
Index: arch/init_mach.c
===================================================================
RCS file: /mint/freemint/sys/arch/init_mach.c,v
retrieving revision 1.29
diff -u -r1.29 init_mach.c
--- arch/init_mach.c	23 Jan 2014 00:32:56 -0000	1.29
+++ arch/init_mach.c	30 May 2015 16:40:46 -0000
@@ -193,7 +193,7 @@
 	/* own FPU test; this must be done after the CPU detection */
 	fputype = detect_fpu ();
 
-	if ((fputype >> 16) > 1)
+	if ((fputype >> 16) > 1 && ((fputype >> 16) & 0x01) == 0)	// coprocessor mode only
 		fpu = 1;
 
 #ifdef WITH_MMU_SUPPORT
@@ -354,31 +354,32 @@
 	}
 	else
 #endif
-	if (fpu)
+	switch (fputype >> 16)
 	{
-		switch (fputype >> 16)
-		{
-			case 0x02:
-				fpu_type = "68881/82";
-				_fpu = " 68881/82 ";
-				break;
-			case 0x04:
-				fpu_type = "68881";
-				_fpu = " 68881 ";
-				break;
-			case 0x06:
-				fpu_type = "68882";
-				_fpu = " 68882 ";
-				break;
-			case 0x08:
-				fpu_type = "68040";
-				_fpu = "/";
-				break;
-			case 0x10:
-				fpu_type = "68060";
-				_fpu = "/";
-				break;
-		}
+		case 0x04:
+			fpu_type = "68881";
+			_fpu = " 68881 ";
+			break;
+		case 0x05:
+			fpu_type = "68881 (SFP-004)";
+			_fpu = " 68881 ";
+			break;
+		case 0x06:
+			fpu_type = "68882";
+			_fpu = " 68882 ";
+			break;
+		case 0x07:
+			fpu_type = "68882 (SFP-004)";
+			_fpu = " 68882 ";
+			break;
+		case 0x08:
+			fpu_type = "68040";
+			_fpu = "/";
+			break;
+		case 0x10:
+			fpu_type = "68060";
+			_fpu = "/";
+			break;
 	}
 
 #ifdef __mcoldfire__
Index: arch/sig_mach.c
===================================================================
RCS file: /mint/freemint/sys/arch/sig_mach.c,v
retrieving revision 1.24
diff -u -r1.24 sig_mach.c
--- arch/sig_mach.c	26 Sep 2012 20:14:27 -0000	1.24
+++ arch/sig_mach.c	30 May 2015 16:40:46 -0000
@@ -540,10 +540,8 @@
 	{
 		CONTEXT *ctxt = &curproc->ctxt[SYSCALL];
 		
-		/* 0x1f38 is a Motorola magic cookie to detect a 68882 idle
-		 * state frame
-		 */
-		if (ctxt->fstate.words[0] == 0x1f38
+		/* 0x38 is the stack frame size value for 68882 */
+		if ((ctxt->fstate.words[0] & 0xff) == 0x38
 			&& ((ctxt->sfmt & 0xfff) >= 0xc0L)
 			&& ((ctxt->sfmt & 0xfff) <= 0xd8L))
 		{