Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Nov 1996 20:47:03 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        dg@Root.COM, smp@csn.net
Cc:        bde@zeta.org.au, hackers@freefall.freebsd.org, smp@freefall.freebsd.org
Subject:   Re: ed0 timeouts
Message-ID:  <199611030947.UAA28658@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>bummer...
>
>Intel says:
>
>It is strongly recommended that first 82489 (ie APIC) should be unmasked
>and then the device interrupt should be enabled.  By this sequence software
>can ensure that always an edge will occur at the APIC input only after
>the interrupt is unmasked.

My version of -current does lazy 8259-masking so that the 8259 doesn't
have to be masked unless the device interrupt repeats.  It would probably
work to never mask it for edge triggered interrupts, but I'm worried
about noise, and level sensitive interrupts need to be handled somehow.

Is the APIC also braindamaged for interrupts masked at the CPU level?

Bruce

Warning: these diffs contain unrelated things (mostly undefined macros)
that won't compile.

diff -c2 icu.s~ icu.s
*** icu.s~	Thu Oct 31 22:48:25 1996
--- icu.s	Thu Oct 31 22:48:27 1996
***************
*** 106,109 ****
--- 106,110 ----
  	jne	doreti_unpend
  doreti_exit:
+ 	CPL_CHANGE_3(%eax)
  	movl	%eax,_cpl
  	decb	_intr_nesting_level
***************
*** 154,157 ****
--- 155,159 ----
  	jae	doreti_swi
  	cli
+ 	CPL_CHANGE_3(%eax)
  	movl	%eax,_cpl
  	MEXITCOUNT
***************
*** 171,175 ****
--- 173,179 ----
  	 */
  	orl	imasks(,%ecx,4),%eax
+ 	CPL_CHANGE_4(%eax)
  	movl	%eax,_cpl
+ 	CPL_CHANGE_4_DONE
  	call	%edx
  	popl	%eax
***************
*** 256,263 ****
--- 260,271 ----
  	pushl	%eax
  	orl	imasks(,%ecx,4),%eax
+ 	CPL_CHANGE_4(%eax)
  	movl	%eax,_cpl
+ 	CPL_CHANGE_4_DONE
  	call	%edx
  	popl	%eax
+ 	CPL_CHANGE_4(%eax)
  	movl	%eax,_cpl
+ 	CPL_CHANGE_4_DONE
  	jmp	splz_next
  
***************
*** 276,279 ****
--- 284,291 ----
  	pushl	%eax
  	cli
+ #define	irq_num	0
+ 	andb	$~IRQ_BIT(irq_num),iactive + IRQ_BYTE(irq_num)
+ 	incl	inotactive_counts + (irq_num) * 4
+ #undef irq_num
  	MEXITCOUNT
  	jmp	_Xintr0			/* XXX might need _Xfastintr0 */
***************
*** 287,290 ****
--- 299,306 ----
  	pushl	%eax
  	cli
+ #define	irq_num	8
+ 	andb	$~IRQ_BIT(irq_num),iactive + IRQ_BYTE(irq_num)
+ 	incl	inotactive_counts + (irq_num) * 4
+ #undef irq_num
  	MEXITCOUNT
  	jmp	_Xintr8			/* XXX might need _Xfastintr8 */
***************
*** 294,299 ****
--- 310,327 ----
  	ALIGN_TEXT ; \
  __CONCAT(vec,irq_num): ; \
+ 	popl	%eax ; \
+ 	pushfl ; \
+ 	pushl	$KCSEL ; \
+ 	pushl	%eax ; \
+ 	cli ; \
+ 	andb	$~IRQ_BIT(irq_num),iactive + IRQ_BYTE(irq_num) ; \
+ 	incl	inotactive_counts + (irq_num) * 4 ; \
+ 	MEXITCOUNT ; \
+ 	jmp	__CONCAT(_Xintr,irq_num)
+ 
+ #if 0
  	int	$ICU_OFFSET + (irq_num) ; \
  	ret
+ #endif
  
  	BUILD_VEC(1)
diff -c2 vector.s~ vector.s
*** vector.s~	Thu Oct 31 22:44:16 1996
--- vector.s	Thu Oct 31 22:45:20 1996
***************
*** 128,131 ****
--- 128,132 ----
  	pushl	_intr_unit + (irq_num) * 4 ; \
  	call	*_intr_handler + (irq_num) * 4 ; /* do the work ASAP */ \
+ 	INTR_ARG_ADJUST ; \
  	enable_icus ;		/* (re)enable ASAP (helps edge trigger?) */ \
  	addl	$4,%esp ; \
***************
*** 136,140 ****
  	notl	%eax ; \
  	andl	_ipending,%eax ; \
! 	jne	1f ;		/* yes, handle them */ \
  	MEXITCOUNT ; \
  	MAYBE_POPL_ES ; \
--- 137,142 ----
  	notl	%eax ; \
  	andl	_ipending,%eax ; \
! 	jne	3f ; 		/* yes, maybe handle them */ \
! 2: ; \
  	MEXITCOUNT ; \
  	MAYBE_POPL_ES ; \
***************
*** 145,152 ****
--- 147,162 ----
  	iret ; \
  ; \
+ 3: ; \
+ 	cmpb	$3,_intr_nesting_level ;	/* is there enough stack? */ \
+ 	jb	1f ;		/* yes, handle unmasked interrupts */ \
+ 	jmp	2b ;		/* no, return */ \
+ ; \
  	ALIGN_TEXT ; \
  1: ; \
+ 	CPL_CHANGE($HWI_MASK|SWI_MASK) ; \
  	movl	_cpl,%eax ; \
+ 	/* XXX next line is probably unnecessary now. */ \
  	movl	$HWI_MASK|SWI_MASK,_cpl ;	/* limit nesting ... */ \
+ 	incb	_intr_nesting_level ;	/* ... really limit it ... */ \
  	sti ;			/* ... to do this as early as possible */ \
  	MAYBE_POPL_ES ;		/* discard most of thin frame ... */ \
***************
*** 164,168 ****
  	pushl	%eax ; \
  	subl	$4,%esp ;	/* junk for unit number */ \
- 	incb	_intr_nesting_level ; \
  	MEXITCOUNT ; \
  	jmp	_doreti
--- 174,177 ----
***************
*** 180,189 ****
  	movl	%ax,%ds ;	/* ... early for obsolete reasons */ \
  	movl	%ax,%es ; \
  	movb	_imen + IRQ_BYTE(irq_num),%al ; \
  	orb	$IRQ_BIT(irq_num),%al ; \
  	movb	%al,_imen + IRQ_BYTE(irq_num) ; \
  	outb	%al,$icu+ICU_IMR_OFFSET ; \
  	enable_icus ; \
- 	incl	_cnt+V_INTR ;	/* tally interrupts */ \
  	movl	_cpl,%eax ; \
  	testb	$IRQ_BIT(irq_num),%reg ; \
--- 189,215 ----
  	movl	%ax,%ds ;	/* ... early for obsolete reasons */ \
  	movl	%ax,%es ; \
+ 	movb	iactive + IRQ_BYTE(irq_num),%al ; \
+ 	testb	$IRQ_BIT(irq_num),%al ; \
+ 	je	1f ; \
+ 	/* XXX skip mcounting here to avoid double count */ \
  	movb	_imen + IRQ_BYTE(irq_num),%al ; \
  	orb	$IRQ_BIT(irq_num),%al ; \
  	movb	%al,_imen + IRQ_BYTE(irq_num) ; \
  	outb	%al,$icu+ICU_IMR_OFFSET ; \
+ 	incl	imen_counts + (irq_num) * 4 ; \
+ 	enable_icus ; \
+ 	orb	$IRQ_BIT(irq_num),_ipending + IRQ_BYTE(irq_num) ; \
+ 	popl	%es ; \
+ 	popl	%ds ; \
+ 	popal ; \
+ 	addl	$4+4,%esp ; \
+ 	iret ; \
+ ; \
+ 	ALIGN_TEXT ; \
+ 1: ; \
+ 	orb	$IRQ_BIT(irq_num),%al ; \
+ 	movb	%al,iactive + IRQ_BYTE(irq_num) ; \
+ 	incl	iactive_counts + (irq_num) * 4 ; \
  	enable_icus ; \
  	movl	_cpl,%eax ; \
  	testb	$IRQ_BIT(irq_num),%reg ; \
***************
*** 192,195 ****
--- 218,222 ----
  __CONCAT(Xresume,irq_num): ; \
  	FAKE_MCOUNT(12*4(%esp)) ;	/* XXX late to avoid double count */ \
+ 	incl	_cnt+V_INTR ;	/* tally interrupts */ \
  	movl	_intr_countp + (irq_num) * 4,%eax ; \
  	incl	(%eax) ; \
***************
*** 198,209 ****
  	pushl	_intr_unit + (irq_num) * 4 ; \
  	orl	_intr_mask + (irq_num) * 4,%eax ; \
  	movl	%eax,_cpl ; \
  	sti ; \
  	call	*_intr_handler + (irq_num) * 4 ; \
! 	cli ;			/* must unmask _imen and icu atomically */ \
  	movb	_imen + IRQ_BYTE(irq_num),%al ; \
  	andb	$~IRQ_BIT(irq_num),%al ; \
  	movb	%al,_imen + IRQ_BYTE(irq_num) ; \
  	outb	%al,$icu+ICU_IMR_OFFSET ; \
  	sti ;			/* XXX _doreti repeats the cli/sti */ \
  	MEXITCOUNT ; \
--- 225,244 ----
  	pushl	_intr_unit + (irq_num) * 4 ; \
  	orl	_intr_mask + (irq_num) * 4,%eax ; \
+ 	CPL_CHANGE_1(%eax, irq_num) ; \
  	movl	%eax,_cpl ; \
  	sti ; \
  	call	*_intr_handler + (irq_num) * 4 ; \
! 	INTR_ARG_ADJUST ; \
! 	cli ;			/* unmask iactive, _imen and icu atomically */ \
! 	andb	$~IRQ_BIT(irq_num),iactive + IRQ_BYTE(irq_num) ; \
! 	incl	inotactive_counts + (irq_num) * 4 ; \
  	movb	_imen + IRQ_BYTE(irq_num),%al ; \
+ 	testb	$IRQ_BIT(irq_num),%al ; \
+ 	je	3f ; \
  	andb	$~IRQ_BIT(irq_num),%al ; \
  	movb	%al,_imen + IRQ_BYTE(irq_num) ; \
  	outb	%al,$icu+ICU_IMR_OFFSET ; \
+ 	incl	inotmen_counts + (irq_num) * 4 ; \
+ 3: ; \
  	sti ;			/* XXX _doreti repeats the cli/sti */ \
  	MEXITCOUNT ; \
***************
*** 258,261 ****
--- 293,306 ----
  
  	.data
+ iactive:
+ 	.long	0
+ iactive_counts:
+ 	.space	NHWI*4
+ inotactive_counts:
+ 	.space	NHWI*4
+ imen_counts:
+ 	.space	NHWI*4
+ inotmen_counts:
+ 	.space	NHWI*4
  ihandlers:			/* addresses of interrupt handlers */
  				/* actually resumption addresses for HWI's */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611030947.UAA28658>