/* * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2006-09-15 QiuYi The first version */ /** * @addtogroup I386 */ /*@{*/ #define ENTRY(proc)\ .align 2;\ .globl proc;\ .type proc,@function;\ proc: #define HDINTERRUPTFNC(name,num) \ ENTRY(name)\ pushl $(num);\ jmp _hdinterrupts;\ .data;\ .long name;\ .text .globl hdinterrupt_func .data .align 4 .type hdinterrupt_func,@object hdinterrupt_func : .text /* the external device interrupts */ HDINTERRUPTFNC(irq0, 0) HDINTERRUPTFNC(irq1, 1) HDINTERRUPTFNC(irq2, 2) HDINTERRUPTFNC(irq3, 3) HDINTERRUPTFNC(irq4, 4) HDINTERRUPTFNC(irq5, 5) HDINTERRUPTFNC(irq6, 6) HDINTERRUPTFNC(irq7, 7) HDINTERRUPTFNC(irq8, 8) HDINTERRUPTFNC(irq9, 9) HDINTERRUPTFNC(irq10, 10) HDINTERRUPTFNC(irq11, 11) HDINTERRUPTFNC(irq12, 12) HDINTERRUPTFNC(irq13, 13) HDINTERRUPTFNC(irq14, 14) HDINTERRUPTFNC(irq15, 15) .p2align 4,0x90 .globl _hdinterrupts .type _hdinterrupts,@function .globl rt_interrupt_enter .globl rt_interrupt_leave .globl rt_hw_isr .globl rt_thread_switch_interrupt_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread _hdinterrupts: push %ds push %es pushal movw $0x10, %ax movw %ax, %ds movw %ax, %es pushl %esp call rt_interrupt_enter movl %esp, %eax /* copy esp to eax */ addl $0x2c, %eax /* move to vector address */ movl (%eax), %eax /* vector(eax) = *eax */ pushl %eax /* push argument : int vector */ call rt_hw_isr add $4, %esp /* restore argument */ call rt_interrupt_leave /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */ movl $rt_thread_switch_interrupt_flag, %eax movl (%eax), %ebx cmp $0x1, %ebx jz _interrupt_thread_switch popl %esp popal pop %es pop %ds add $4,%esp iret _interrupt_thread_switch: popl %esp movl $0x0, %ebx movl %ebx, (%eax) movl $rt_interrupt_from_thread, %eax movl (%eax), %ebx movl %esp, (%ebx) movl $rt_interrupt_to_thread, %ecx movl (%ecx), %edx movl (%edx), %esp popal pop %es pop %ds add $4,%esp iret /*@}*/