Subject: Re: bge/ahd interrupt problems: partly resolved (hardware bug)
To: =?ISO-8859-1?Q?Edgar_Fu=DF?= <ef@math.uni-bonn.de>
From: Frank van der Linden <fvdl@netbsd.org>
List: port-amd64
Date: 03/26/2007 15:09:00
This is a multi-part message in MIME format.
--------------000300020909070503090201
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Edgar Fuß wrote:
>> Just out of curiosity, what is the reported version of the ioapic in 
>> question?
> It's 11 (hex) for all three of them. I guess one is in the CPU and the 
> other two are inside the 8131.
Try the attached diff, it mimics the Linux behavior.

Note: I don't have time to actually test it right now, so I only 
compile-tested it. I can't guarantee that your system will boot with it :-)

- Frank


--------------000300020909070503090201
Content-Type: text/x-diff; x-mac-type="0"; x-mac-creator="0";
 name="ioapic.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ioapic.diff"

Index: amd64/genassym.cf
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/genassym.cf,v
retrieving revision 1.8
diff -c -r1.8 genassym.cf
*** amd64/genassym.cf	18 Feb 2007 08:08:41 -0000	1.8
--- amd64/genassym.cf	26 Mar 2007 13:05:59 -0000
***************
*** 274,279 ****
--- 274,280 ----
  define	IS_PIN		offsetof(struct intrsource, is_pin)
  define	IS_TYPE		offsetof(struct intrsource, is_type)
  define	IS_MAXLEVEL	offsetof(struct intrsource, is_maxlevel)
+ define	IS_IDTVEC	offsetof(struct intrsource, is_idtvec)
  
  define	MTX_IPL			offsetof(struct kmutex, u.s.mtxs_ipl)
  define	MTX_LOCK		offsetof(struct kmutex, u.s.mtxs_lock)
Index: amd64/vector.S
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/vector.S,v
retrieving revision 1.10
diff -c -r1.10 vector.S
*** amd64/vector.S	9 Feb 2007 21:55:01 -0000	1.10
--- amd64/vector.S	26 Mar 2007 13:05:59 -0000
***************
*** 490,560 ****
  
  #if NIOAPIC > 0
  
! INTRSTUB(ioapic_edge,0,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,1,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,2,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,3,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,4,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,5,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,6,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,7,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,8,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,9,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,10,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,11,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,12,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,13,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,14,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,15,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,16,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,17,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,18,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,19,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,20,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,21,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,22,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,23,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,24,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,25,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,26,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,27,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,28,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,29,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,30,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,31,voidop,ioapic_asm_ack,voidop,voidop,voidop)
! 
! INTRSTUB(ioapic_level,0,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,1,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,2,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,3,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,4,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,5,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,6,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,7,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,8,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,9,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,10,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,11,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,12,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,13,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,14,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,15,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,16,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,17,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,18,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,19,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,20,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,21,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,22,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,23,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,24,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,25,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,26,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,27,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,28,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,29,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,30,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
! INTRSTUB(ioapic_level,31,voidop,ioapic_asm_ack,voidop,ioapic_unmask,ioapic_mask)
  
  #endif
  
--- 490,592 ----
  
  #if NIOAPIC > 0
  
! INTRSTUB(ioapic_edge,0,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,1,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,2,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,3,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,4,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,5,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,6,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,7,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,8,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,9,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,10,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,11,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,12,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,13,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,14,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,15,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,16,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,17,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,18,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,19,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,20,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,21,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,22,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,23,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,24,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,25,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,26,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,27,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,28,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,29,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,30,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! INTRSTUB(ioapic_edge,31,voidop,ioapic_asm_edge_ack,voidop,voidop,voidop)
! 
! INTRSTUB(ioapic_level,0,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,1,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,2,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,3,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,4,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,5,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,6,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,7,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,8,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,9,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,10,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,11,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,12,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,13,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,14,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,15,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,16,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,17,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,18,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,19,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,20,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,21,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,22,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,23,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,24,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,25,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,26,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,27,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,28,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,29,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,30,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
! INTRSTUB(ioapic_level,31,voidop,ioapic_asm_level_ack,voidop,ioapic_unmask,
!     ioapic_mask)
  
  #endif
  
Index: include/i82093reg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/include/i82093reg.h,v
retrieving revision 1.3
diff -c -r1.3 i82093reg.h
*** include/i82093reg.h	11 May 2003 15:46:57 -0000	1.3
--- include/i82093reg.h	26 Mar 2007 13:05:59 -0000
***************
*** 8,15 ****
  #include "opt_multiprocessor.h"
  #endif
  
! #define ioapic_asm_ack(num) \
! 	movl	$0,(_C_LABEL(local_apic)+LAPIC_EOI)(%rip)
  
  #ifdef MULTIPROCESSOR
  
--- 8,45 ----
  #include "opt_multiprocessor.h"
  #endif
  
! #define ioapic_asm_edge_ack(num) \
! 	movl    $0,(_C_LABEL(local_apic)+LAPIC_EOI)(%rip)
! 
! #define ioapic_asm_level_ack(num) \
! 	leaq	_C_LABEL(local_apic)(%rip),%rax			;\
! 	movl	IS_IDTVEC(%r14),%esi				;\
! 	movq	%rsi,%rdi					;\
! 	andl	$0xffffffe0,%edi				;\
! 	shrq	%rdi						;\
! 	movl	LAPIC_TMR(%rax,%rdi),%r15d			;\
! 	movl	$0,LAPIC_EOI(%rax)				;\
! 	andl	$0x1f,%esi					;\
! 	bt	%esi,%r15d					;\
! 	jc	76f						;\
! 	movq	IS_PIC(%r14),%rdi				;\
! 	ioapic_asm_lock(num)					;\
! 	movl	IS_PIN(%r14),%esi				;\
! 	leaq	0x10(%rsi,%rsi,1),%rsi				;\
! 	movq	IOAPIC_SC_REG(%rdi),%r15			;\
! 	movl	%esi, (%r15)					;\
! 	movq	IOAPIC_SC_DATA(%rdi),%r13			;\
! 	movl	(%r13),%r12d					;\
! 	orl	$IOAPIC_REDLO_MASK,%r12d			;\
! 	andl	$~IOAPIC_REDLO_LEVEL,%r12d			;\
! 	movl	%r12d,(%r13)					;\
! 	movl	%esi, (%r15)					;\
! 	movl	(%r13),%r12d					;\
! 	andl	$~IOAPIC_REDLO_MASK,%r12d			;\
! 	orl	$IOAPIC_REDLO_LEVEL,%r12d			;\
! 	movl	%r12d,(%r13)					;\
! 	ioapic_asm_unlock(num)					;\
! 76:
  
  #ifdef MULTIPROCESSOR
  
***************
*** 56,62 ****
  	movl	%esi, (%r15)					;\
  	movl	(%r13),%r12d					;\
  	andl	$~IOAPIC_REDLO_MASK,%r12d			;\
- 	movl	%esi,(%r15)					;\
  	movl	%r12d,(%r13)					;\
  	ioapic_asm_unlock(num)					;\
  79:
--- 86,91 ----

--------------000300020909070503090201--