荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: GyeaonWoo (柏林恋人), 信区: Linux
标  题: Linus's Linux--kernel/rs_io.s
发信站: 荔园晨风BBS站 (Mon Aug 25 20:50:18 2003), 站内信件

/*
 *      rs_io.s
 *
 * This module implements the rs232 io interrupts.
 */

.text
.globl _rs1_interrupt,_rs2_interrupt

size    = 1024                          /* must be power of two !
                                           and must match the value
                                           in tty_io.c!!! */

/* these are the offsets into the read/write buffer structures */
rs_addr = 0
head = 4
tail = 8
proc_list = 12
buf = 16

startup = 256           /* chars left in write queue when we restart it */

/*
 * These are the actual interrupt routines. They look where
 * the interrupt is coming from, and take appropriate action.
 */
.align 2
_rs1_interrupt:
        pushl $_table_list+8
        jmp rs_int
.align 2
_rs2_interrupt:
        pushl $_table_list+16
rs_int:
        pushl %edx
        pushl %ecx
        pushl %ebx
        pushl %eax
        push %es
        push %ds                /* as this is an interrupt, we cannot */
        pushl $0x10             /* know that bs is ok. Load it */
        pop %ds
        pushl $0x10
        pop %es
        movl 24(%esp),%edx
        movl (%edx),%edx
        movl rs_addr(%edx),%edx
        addl $2,%edx            /* interrupt ident. reg */
rep_int:
        xorl %eax,%eax
        inb %dx,%al
        testb $1,%al
        jne end
        cmpb $6,%al             /* this shouldn't happen, but ... */
        ja end
        movl 24(%esp),%ecx
        pushl %edx
        subl $2,%edx
        call jmp_table(,%eax,2)         /* NOTE! not *4, bit0 is 0 already */
        popl %edx
        jmp rep_int
end:    movb $0x20,%al
        outb %al,$0x20          /* EOI */
        pop %ds
        pop %es
        popl %eax
        popl %ebx
        popl %ecx
        popl %edx
        addl $4,%esp            # jump over _table_list entry
        iret

jmp_table:
        .long modem_status,write_char,read_char,line_status

.align 2
modem_status:
        addl $6,%edx            /* clear intr by reading modem status reg */
        inb %dx,%al
        ret

.align 2
line_status:
        addl $5,%edx            /* clear intr by reading line status reg. */
        inb %dx,%al
        ret

.align 2
read_char:
        inb %dx,%al
        movl %ecx,%edx
        subl $_table_list,%edx
        shrl $3,%edx
        movl (%ecx),%ecx                # read-queue
        movl head(%ecx),%ebx
        movb %al,buf(%ecx,%ebx)
        incl %ebx
        andl $size-1,%ebx
        cmpl tail(%ecx),%ebx
        je 1f
        movl %ebx,head(%ecx)
        pushl %edx
        call _do_tty_interrupt
        addl $4,%esp
1:      ret

.align 2
write_char:
        movl 4(%ecx),%ecx               # write-queue
        movl head(%ecx),%ebx
        subl tail(%ecx),%ebx
        andl $size-1,%ebx               # nr chars in queue
        je write_buffer_empty
        cmpl $startup,%ebx
        ja 1f
        movl proc_list(%ecx),%ebx       # wake up sleeping process
        testl %ebx,%ebx                 # is there any?
        je 1f
        movl $0,(%ebx)
1:      movl tail(%ecx),%ebx
        movb buf(%ecx,%ebx),%al
        outb %al,%dx
        incl %ebx
        andl $size-1,%ebx
        movl %ebx,tail(%ecx)
        cmpl head(%ecx),%ebx
        je write_buffer_empty
        ret
.align 2
write_buffer_empty:
        movl proc_list(%ecx),%ebx       # wake up sleeping process
        testl %ebx,%ebx                 # is there any?
        je 1f
        movl $0,(%ebx)
1:      incl %edx
        inb %dx,%al
        jmp 1f
1:      jmp 1f
1:      andb $0xd,%al           /* disable transmit interrupt */
        outb %al,%dx
        ret

--
泉水白白流淌
花朵为谁开放
是这样美丽负伤的麦子
吐着芳香
站在山岗上

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.35.5]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店