From: Juan Perez-Sanchez <lithoxs@gmail.com>
To: linux-8086 <linux-8086@vger.kernel.org>
Subject: Bugs in irqtab.c and patches
Date: Mon, 30 Jan 2012 18:36:44 -0600 [thread overview]
Message-ID: <CAD6VGubiLt0dcwGqyhw1RMp5ExpLy5zSFq69CLx23Hq7ahn8gQ@mail.gmail.com> (raw)
Hi,
I found 3 bugs in file arch/i86/kernel/irqtab.c:
1. Interrupt #15 was considered a trap and the corresponding EOI
not sent, rendering this
interrupt useless after servicing the first interrupt.
2. Interrupts in the slave controller are masked after servicing
the first interrupt, rendering
these interrupts useless.
3. In interrupt #0, the bios service routine is invoked once every
5 interrupts. When this
happens, both ELKS and BIOS interrupts service routines send
EOI to the interrupt
controller, probably disrupting its internal operation.
In addition to fixing the above bugs, the following patch reduces
the code size in at least
50 bytes. After applying the patch, the kernel Image was built and the
a test machine booted the modified kernel.
greetings,
Juan
diff -Nurb elks.orig/arch/i86/kernel/irqtab.c elks/arch/i86/kernel/irqtab.c
--- elks.orig/arch/i86/kernel/irqtab.c 2002-10-31 19:04:25.000000000 -0600
+++ elks/arch/i86/kernel/irqtab.c 2012-01-30 18:52:15.000000000 -0600
@@ -36,6 +36,11 @@
#define bios_call_cnt cseg_bios_call_cnt
#endif
+#ifdef CONFIG_ROMCODE
+ #define SEG_IRQ_DATA es
+#else
+ #define SEG_IRQ_DATA cs
+#endif
#ifndef S_SPLINT_S
#asm
@@ -105,34 +110,32 @@
mov dx,ds ;the original value
cli ;just here
- xor ax,ax
- mov es,ax ;intr table
-
#ifdef CONFIG_ROMCODE
mov ax,#CONFIG_ROM_IRQ_DATA
-#else
- mov ax,cs
+ mov es,ax
#endif
- mov ds,ax
-
+ seg SEG_IRQ_DATA
mov stashed_ds,dx
+ xor ax,ax
+ mov es,ax ;intr table
+
seg es ;insert new timer intr
mov bx,[32]
- mov off_stashed_irq0, bx ; the old one
- lea ax,_irq0
+ mov off_stashed_irq0_l, bx ; the old one
+ mov ax,#_irq0
seg es
mov [32],ax
seg es
mov bx,[34]
- mov seg_stashed_irq0, bx
+ mov seg_stashed_irq0_l, bx
mov ax,cs
seg es
mov [34],ax
-
+ mov [bios_call_cnt_l],#5 ; init bios timer int. call counter
#ifndef CONFIG_CONSOLE_BIOS
- lea ax,_irq1 ;keyboard
+ mov ax,#_irq1 ;keyboard
seg es
mov [36],ax
mov ax,cs
@@ -141,7 +144,7 @@
#endif
#if 0
- lea ax,_irq2
+ mov ax,#_irq2
seg es
mov [40],ax
mov ax,cs
@@ -149,14 +152,14 @@
mov [42],ax
#endif
- lea ax,_irq3 ;com2
+ mov ax,#_irq3 ;com2
seg es
mov [44],ax
mov ax,cs
seg es
mov [46],ax
- lea ax,_irq4 ;com1
+ mov ax,#_irq4 ;com1
seg es
mov [48],ax
mov ax,cs
@@ -165,7 +168,7 @@
! Setup INT 0x80 (for syscall)
- lea ax,_syscall_int
+ mov ax,#_syscall_int
seg es
mov [512],ax
mov ax,cs
@@ -223,65 +226,65 @@
mov ax,#1
br _irqit
#if 0
-_irq2:
+_irq2: ;XT: EGA vert retrace; AT: cascade
push ax
mov ax,#2
br _irqit
#endif
-_irq3: ;com2
+_irq3: ;com2 & com4
push ax
mov ax,#3
br _irqit
-_irq4: ;com1
+_irq4: ;com1 & com3
push ax
mov ax,#4
br _irqit
#if 0
-_irq5:
+_irq5: ;XT: fixed disk controller; AT: lpt2
push ax
mov ax,#5
br _irqit
-_irq6:
+_irq6: ;floppy disk controller
push ax
mov ax,#6
br _irqit
-_irq7:
+_irq7: ;lpt1 printer controller
push ax
mov ax,#7
br _irqit
!
! AT interrupts
!
-_irq8:
+_irq8: ;real time clock
push ax
mov ax,#8
br _irqit
-_irq9:
+_irq9: ;redirect cascade
push ax
mov ax,#9
br _irqit
-_irq10:
+_irq10: ;
push ax
mov ax,#10
br _irqit
-_irq11:
+_irq11: ;
push ax
mov ax,#11
jmp _irqit
-_irq12:
+_irq12: ;ps2 mouse
push ax
mov ax,#12
jmp _irqit
-_irq13:
+_irq13: ;math coprocessor
push ax
mov ax,#13
jmp _irqit
-_irq14:
+_irq14: ;fixed disk controller 1
push ax
mov ax,#14
jmp _irqit
-_irq15:
+_irq15: ;fixed disk controller 2
push ax
mov ax,#15
jmp _irqit
@@ -445,27 +448,25 @@
!
#ifdef CONFIG_ROMCODE
mov bx,#CONFIG_ROM_IRQ_DATA
-#else
- mov bx,cs
+ mov es,bx
#endif
+!
+! Switch segments
+!
+ seg SEG_IRQ_DATA
+ mov bx,stashed_ds ! Recover the data segment
mov ds,bx
- mov stashed_irq,ax ! Save IRQ number
+ mov stashed_irq_l,ax ! Save IRQ number
mov ax,ss ! Get current SS
mov bx,ax ! Save for later
- mov stashed_ss, ax ! Save SS:SP
- mov ax,sp
- mov stashed_sp, ax
-!
-! Switch segments
-!
- mov ax,stashed_ds ! Recover the data segment
- mov ds,ax
- mov es,ax
+ mov stashed_ss_l,ax ! Save SS:SP
+ mov stashed_sp_l,sp
+ movb cl,bios_call_cnt_l
!
! Set up task switch controller
!
- xor ch,ch ! Assume we are not allowed to switch
+ xorb ch,ch ! Assume we are not allowed to switch
!
! See where we were (BX holds the SS on entry)
!
@@ -482,7 +483,6 @@
! Bios etc - switch to interrupt stack
!
mov sp,#_intstack
-! lea sp, _intstack
j switched
!
! User task. Extract kernel SP. (BX already holds current)
@@ -491,8 +491,6 @@
mov ax,[bx] ! kernel stack ptr
mov sp,ax ! switch to kernel stack
inc ch ! Switch allowable
- j switched
-ktask:
!
! In ktask state we have a suitable stack. It might be
! better to use the intstack..
@@ -500,25 +498,15 @@
switched:
mov ax,ds
mov ss,ax ! /* Set SS: right */
+ mov es,ax ! /* Set ES: right */
+ktask:
! /*
! Put the old SS;SP on the top of the stack. We can't
! leave them in stashed_ss/sp as we could re-enter the
! routine on a reschedule.
! */
-#ifdef CONFIG_ROMCODE
- mov ax,#CONFIG_ROM_IRQ_DATA
- mov es,ax
- seg es
- push stashed_sp
- seg es
- push stashed_ss
-
-#else
- seg cs
- push stashed_sp
- seg cs
- push stashed_ss
-#endif
+ push stashed_sp_l
+ push stashed_ss_l
!
! We are on a suitable stack and cx says whether we can
! switch afterwards. The C code will want to eat CX so
@@ -530,19 +518,12 @@
mov bp,sp
mov _can_tswitch, ch
push cx ! Save ch
-#ifdef CONFIG_ROMCODE
- seg es
-#else
- seg cs ! Recover the IRQ we saved
-#endif
- mov ax,stashed_irq
+ mov ax,stashed_irq_l ! Recover the IRQ we saved
push ax ! IRQ for later
push bp ! Register base
push ax ! IRQ number
-#ifdef CONFIG_ROMCODE
mov ax,ds
- mov es,ax ;es back to dataseg
-#endif
+ mov es,ax ! es back to dataseg
!
! Call the C code
!
@@ -557,52 +538,30 @@
!
! Restore any chips
!
- cmp ax,#15
+ cmp ax,#16
jge was_trap ! Traps need no reset
- cmp ax,#8
- jge sec_8259 ! IRQ on low chip
-!
-! Reset primary 8259
-!
+ or ax,ax ! Is int #0?
+ jnz a4
+ dec cl ! Will call bios int?
+ je was_trap
+a4:
mov cl,al ! Save the IRQ number
- inb al,0x21 ! The chip line state
- jmp a7
-a7: jmp a8
-a8:
-! movb al,#1
-! shl al,cl ! Shift the irq (saved in cl) to a mask
-! orb al,_cache_21
-! movb _cache_21, al
- movb al,_cache_21 ! Extract the IRQ mask register
- outb 0x21,al ! Now ack the IRQ
- jmp a9
-a9: jmp a10
-a10: movb al,#0x20 ! EOI
- outb 0x20,al
- jmp was_trap
-
+ movb al,#0x20 ! EOI
+ cmp cl,#8
+ jb pri_8259 ! IRQ on low chip
!
! Reset secondary 8259 if we have taken an AT rather
! than XT irq. We also have to prod the primay
! controller EOI..
!
-sec_8259:
- mov cl,al ! Save the IRQ for making masks
- inb al,0xA1
- jmp a1
-a1: jmp a2
-a2: movb al,#1
- shl al,cl
- orb al,_cache_A1
- movb _cache_A1, al
- outb 0xA1,al ! Now ack the IRQ
- jmp a3
-a3: jmp a4
-a4: movb al,#0x20
outb 0xA0,al
jmp a5
-a5: jmp a6
-a6: outb 0x20,al ! Ack on primary controller
+a5: jmp pri_8259
+!
+! Reset primary 8259
+!
+pri_8259:
+ outb 0x20,al ! Ack on primary controller
!
! And a trap does no hardware work
@@ -655,83 +614,44 @@
pop cx
pop bx
pop es
-#ifdef CONFIG_ROMCODE
- mov ax,#CONFIG_ROM_IRQ_DATA
- mov ds,ax
-#else
- seg cs
-#endif
- mov ax, stashed_irq
- or ax,ax
- jz irq0_bios
- pop ds
- pop ax
-!
-! Iret restores CS:IP and F (thus including the interrupt bit)
-!
- iret
+ cmp stashed_irq_l,#0
+ jnz no_bios_call
!
! IRQ 0 (timer) has to go on to the bios for some systems
!
-! FIXME: should call the bios only every fifth event.
-!
irq0_bios:
- pop ds
- pop ax ;now the stack empty
-
-;------------------------------------------------
-;Build new Stack
-;
-; SP -> RET seg
-; RET offs
-; SP-4 -> BP
-; SP-4 -> BX
-; DS
-; SP-8 -> free ;sp
-label1:
-
- sub sp,#4 ;space for retf
- push bp
- mov bp,sp
-
- push bx
- push ds
-#ifdef CONFIG_ROMCODE
- mov bx,#CONFIG_ROM_IRQ_DATA
-#else
- mov bx,cs
-#endif
- mov ds,bx
- mov bx,bios_call_cnt
- inc bx
- cmp bx,#5
+ dec [bios_call_cnt_l]
jne no_bios_call
-
- xor bx,bx
- mov bios_call_cnt,bx
- mov bx, seg_stashed_irq0
- mov [bp+4], bx
- mov bx, off_stashed_irq0
- mov [bp+2], bx
-
+ mov [bios_call_cnt_l],#5
+ pushf
+ callf [off_stashed_irq0_l]
+no_bios_call:
pop ds
- pop bx
- pop bp
- retf
-
-no_bios_call: ;sp-8
- mov bios_call_cnt,bx
- pop ds
- pop bx ;sp-4
- pop bp
- add sp,#4
+ pop ax ;now the stack empty
+!
+! Iret restores CS:IP and F (thus including the interrupt bit)
+!
iret
.data
.globl _can_tswitch
_can_tswitch:
.byte 0
+
+off_stashed_irq0_l:
+ .word 0
+seg_stashed_irq0_l:
+ .word 0
+stashed_sp_l:
+ .word 0
+stashed_ss_l:
+ .word 0
+stashed_irq_l:
+ .word 0
+bios_call_cnt_l:
+ .word 0
+
.zerow 256 ! (was) 128 byte interrupt stack
_intstack:
reply other threads:[~2012-01-31 0:36 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAD6VGubiLt0dcwGqyhw1RMp5ExpLy5zSFq69CLx23Hq7ahn8gQ@mail.gmail.com \
--to=lithoxs@gmail.com \
--cc=linux-8086@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).