Subject: _fpfault problem
To: None <port-m68k@NetBSD.ORG>
From: Ignatios Souvatzis <ignatios@cs.uni-bonn.de>
List: port-m68k
Date: 05/05/1996 18:43:04
Hello,

when checking for things to do for 68060 support integration, I saw
that in each and every m68k port (checked today after cvs update'ing)
the following piece of code is found in every locore.s:

_fpfault:
#ifdef FPCOPROC
	clrl	sp@-		| stack adjust count
	moveml	#0xFFFF,sp@-	| save user registers
	movl	usp,a0		| and save
	movl	a0,sp@(FR_SP)	|   the user stack pointer
	clrl	sp@-		| no VA arg
	movl	_curpcb,a0	| current pcb
	lea	a0@(PCB_FPCTX),a0 | address of FP savearea
	fsave	a0@		| save state
	tstb	a0@		| null state frame?
	jeq	Lfptnull	| yes, safe
	clrw	d0		| no, need to tweak BIU
	movb	a0@(1),d0	| get frame size
	bset	#3,a0@(0,d0:w)	| set exc_pend bit of BIU
Lfptnull:

...

This code (or maybe a variation of it) is necessary for the M68881/2
coprocessor (else we would get the same exception again if the program
continues to run after servicing the signal); but it is really really
wrong for 68040 (and 68060) (cf. 68040 UM/AD rev 1, p. 9-41 - 9-42).

I propose something like this:

_fpfault:
#ifdef FPCOPROC
	clrl	sp@-		| stack adjust count
	moveml	#0xFFFF,sp@-	| save user registers
	movl	usp,a0		| and save
	movl	a0,sp@(FR_SP)	|   the user stack pointer
	clrl	sp@-		| no VA arg
	movl	_curpcb,a0	| current pcb
	lea	a0@(PCB_FPCTX),a0 | address of FP savearea
	fsave	a0@		| save state
|XXX --new code here---
	test_for_040_or_060	|XXX replace with appropriate code
	jiftrue	Lfptnull	|XXX for your port.
| on non-060 machines, you can use 
|	cmpb	#0x41,a0@	| is it the 68040 FPU frame format?
|	jeq	Lfptnull
| on Amiga, we would use
|	movb	_machineid+3,d0
|	andb	#0x90,d0	| (AMIGA_68060|AMIGA_68040)
|	jne	Lfptnull	| btw, this has to come before the 
				| tstb a0@ below, as the 68060 has a
				| different NULL FPU state frame format
|XXX --- original code continues ---
	tstb	a0@		| null state frame?
	jeq	Lfptnull	| yes, safe
|XXX I'm not sure if the following code is really necessary, I'll
|XXX check when I get my hands on original Motorola 68881/2 docs:
	movb	a0@(1),d0	| get frame size
	and	#0xdf,d0
	cmp	#0x18,d0	| is it a BUSY frame?
	jne	Lfptnull
|XXX --- original code continues ---
	clrw	d0		| no, need to tweak BIU
	movb	a0@(1),d0	| get frame size
	bset	#3,a0@(0,d0:w)	| set exc_pend bit of BIU
Lfptnull:

Regards,
	Ignatios Souvatzis