URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [i386/] [shared/] [irq/] [irq_asm.S] - Rev 507
Go to most recent revision | Compare with Previous | Blame | View Log
/* irq.c** This file contains the implementation of the function described in irq.h** CopyRight (C) 1998 valette@crf.canon.fr** The license and distribution terms for this file may be* found in found in the file LICENSE in this distribution or at* http://www.OARcorp.com/rtems/license.html.** $Id: irq_asm.S,v 1.2 2001-09-27 11:59:49 chris Exp $*/#include "asm.h"#include <irq_asm.h>BEGIN_CODESYM (_ISR_Handler):/** Before this was point is reached the vectors unique* entry point did the following:** 1. saved scratch registers registers eax edx ecx"* 2. put the vector number in ecx.** BEGINNING OF ESTABLISH SEGMENTS** WARNING: If an interrupt can occur when the segments are* not correct, then this is where we should establish* the segments. In addition to establishing the* segments, it may be necessary to establish a stack* in the current data area on the outermost interrupt.** NOTE: If the previous values of the segment registers are* pushed, do not forget to adjust SAVED_REGS.** NOTE: Make sure the exit code which restores these* when this type of code is needed.*//***** ESTABLISH SEGMENTS CODE GOES HERE ******//** END OF ESTABLISH SEGMENTS*//** Now switch stacks if necessary*/movw SYM (i8259s_cache), ax # move current i8259 interrupt mask in axpushl eax # push it on the stack/** compute the new PIC mask:** <new mask> = <old mask> | irq_mask_or_tbl[<intr number aka ecx>]*/movw SYM (irq_mask_or_tbl) (,ecx,2), dxorw dx, ax/** Install new computed value on the i8259 and update cache* accordingly*/movw ax, SYM (i8259s_cache)outb $PIC_MASTER_IMR_IO_PORTmovb ah, aloutb $PIC_SLAVE_IMR_IO_PORT/** acknowledge the interrupt**/movb $PIC_EOI, alcmpl $7, ecxjbe .masteroutb $PIC_SLAVE_COMMAND_IO_PORT.master:outb $PIC_MASTER_COMMAND_IO_PORT.check_stack_switch:pushl ebpmovl esp, ebp # ebp = previous stack pointercmpl $0, SYM (_ISR_Nest_level) # is this the outermost interrupt?jne nested # No, then continuemovl SYM (_CPU_Interrupt_stack_high), esp/** We want to insure that the old stack pointer is on the* stack we will be on at the end of the ISR when we restore it.* By saving it on every interrupt, all we have to do is pop it* near the end of every interrupt.*/nested:incl SYM (_ISR_Nest_level) # one nest level deeperincl SYM (_Thread_Dispatch_disable_level) # disable multitasking/** re-enable interrupts at processor level as the current* interrupt source is now masked via i8259*/sti/** ECX is preloaded with the vector number but it is a scratch register* so we must save it again.*/pushl ecx # push vector numbermov SYM (current_irq) (,ecx,4),eax# eax = Users handlercall *eax # invoke user ISR/** disable interrupts_again*/clipopl ecx # ecx = vector number/** restore stack*/movl ebp, esppopl ebp/** restore the original i8259 masks*/popl eaxmovw ax, SYM (i8259s_cache)outb $PIC_MASTER_IMR_IO_PORTmovb ah, aloutb $PIC_SLAVE_IMR_IO_PORTdecl SYM (_ISR_Nest_level) # one less ISR nest level# If interrupts are nested,# then dispatching is disableddecl SYM (_Thread_Dispatch_disable_level)# unnest multitasking# Is dispatch disabledjne .exit # Yes, then exitcmpl $0, SYM (_Context_Switch_necessary)# Is task switch necessary?jne .schedule # Yes, then call the schedulercmpl $0, SYM (_ISR_Signals_to_thread_executing)# signals sent to Run_thread# while in interrupt handler?je .exit # No, exit.bframe:movl $0, SYM (_ISR_Signals_to_thread_executing)/** This code is the less critical path. In order to have a single* Thread Context, we take the same frame than the one pushed on* exceptions. This makes sense because Signal is a software* exception.*/popl edxpopl ecxpopl eaxpushl $0 # fake fault codepushl $0 # fake exception numberpushapushl espcall _ThreadProcessSignalsFromIrqaddl $4, esppopaaddl $8, espiret.schedule:/** the scratch registers have already been saved and we are already* back on the thread system stack. So we can call _Thread_Displatch* directly*/call _Thread_Dispatch/** fall through exit to restore complete contex (scratch registers* eip, CS, Flags).*/.exit:/** BEGINNING OF DE-ESTABLISH SEGMENTS** NOTE: Make sure there is code here if code is added to* load the segment registers.**//******* DE-ESTABLISH SEGMENTS CODE GOES HERE ********//** END OF DE-ESTABLISH SEGMENTS*/popl edxpopl ecxpopl eaxiret#define DISTINCT_INTERRUPT_ENTRY(_vector) \.p2align 4 ; \PUBLIC (rtems_irq_prologue_ ## _vector ) ; \SYM (rtems_irq_prologue_ ## _vector ): \pushl eax ; \pushl ecx ; \pushl edx ; \movl $ _vector, ecx ; \jmp SYM (_ISR_Handler) ;DISTINCT_INTERRUPT_ENTRY(0)DISTINCT_INTERRUPT_ENTRY(1)DISTINCT_INTERRUPT_ENTRY(2)DISTINCT_INTERRUPT_ENTRY(3)DISTINCT_INTERRUPT_ENTRY(4)DISTINCT_INTERRUPT_ENTRY(5)DISTINCT_INTERRUPT_ENTRY(6)DISTINCT_INTERRUPT_ENTRY(7)DISTINCT_INTERRUPT_ENTRY(8)DISTINCT_INTERRUPT_ENTRY(9)DISTINCT_INTERRUPT_ENTRY(10)DISTINCT_INTERRUPT_ENTRY(11)DISTINCT_INTERRUPT_ENTRY(12)DISTINCT_INTERRUPT_ENTRY(13)DISTINCT_INTERRUPT_ENTRY(14)DISTINCT_INTERRUPT_ENTRY(15)/** routine used to initialize the IDT by default*/PUBLIC (default_raw_idt_handler)PUBLIC (raw_idt_notify)SYM (default_raw_idt_handler):pushacldcall raw_idt_notifypopairetEND_CODEEND
Go to most recent revision | Compare with Previous | Blame | View Log
