summaryrefslogtreecommitdiffstats
path: root/c/src/exec/score/cpu/i386/cpu_asm.s
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-05-11 17:39:37 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-05-11 17:39:37 +0000
commitac7d5ef06a6d6e8d84abbd1f0b82162725f98326 (patch)
tree9304cf759a73f2a1c6fd3191948f00e870af3787 /c/src/exec/score/cpu/i386/cpu_asm.s
downloadrtems-ac7d5ef06a6d6e8d84abbd1f0b82162725f98326.tar.bz2
Initial revision
Diffstat (limited to 'c/src/exec/score/cpu/i386/cpu_asm.s')
-rw-r--r--c/src/exec/score/cpu/i386/cpu_asm.s654
1 files changed, 654 insertions, 0 deletions
diff --git a/c/src/exec/score/cpu/i386/cpu_asm.s b/c/src/exec/score/cpu/i386/cpu_asm.s
new file mode 100644
index 0000000000..121b4409d9
--- /dev/null
+++ b/c/src/exec/score/cpu/i386/cpu_asm.s
@@ -0,0 +1,654 @@
+/* cpu_asm.s
+ *
+ * This file contains all assembly code for the Intel i386 implementation
+ * of RTEMS.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <asm.h>
+
+/*
+ * Format of i386 Register structure
+ */
+
+.set REG_EFLAGS, 0
+.set REG_ESP, REG_EFLAGS + 4
+.set REG_EBP, REG_ESP + 4
+.set REG_EBX, REG_EBP + 4
+.set REG_ESI, REG_EBX + 4
+.set REG_EDI, REG_ESI + 4
+.set SIZE_REGS, REG_EDI + 4
+
+ BEGIN_CODE
+
+/*
+ * void _CPU_Context_switch( run_context, heir_context )
+ *
+ * This routine performs a normal non-FP context.
+ */
+
+ .align 2
+ PUBLIC (_CPU_Context_switch)
+
+.set RUNCONTEXT_ARG, 4 # save context argument
+.set HEIRCONTEXT_ARG, 8 # restore context argument
+
+SYM (_CPU_Context_switch):
+ movl RUNCONTEXT_ARG(esp),eax # eax = running threads context
+ pushf # push eflags
+ popl REG_EFLAGS(eax) # save eflags
+ movl esp,REG_ESP(eax) # save stack pointer
+ movl ebp,REG_EBP(eax) # save base pointer
+ movl ebx,REG_EBX(eax) # save ebx
+ movl esi,REG_ESI(eax) # save source register
+ movl edi,REG_EDI(eax) # save destination register
+
+ movl HEIRCONTEXT_ARG(esp),eax # eax = heir threads context
+
+restore:
+ pushl REG_EFLAGS(eax) # push eflags
+ popf # restore eflags
+ movl REG_ESP(eax),esp # restore stack pointer
+ movl REG_EBP(eax),ebp # restore base pointer
+ movl REG_EBX(eax),ebx # restore ebx
+ movl REG_ESI(eax),esi # restore source register
+ movl REG_EDI(eax),edi # restore destination register
+ ret
+
+/*
+ * NOTE: May be unnecessary to reload some registers.
+ */
+
+/*
+ * void _CPU_Context_restore( new_context )
+ *
+ * This routine performs a normal non-FP context.
+ */
+
+ PUBLIC (_CPU_Context_restore)
+
+.set NEWCONTEXT_ARG, 4 # context to restore argument
+
+SYM (_CPU_Context_restore):
+
+ movl NEWCONTEXT_ARG(esp),eax # eax = running threads context
+ jmp restore
+
+/*PAGE
+ * void _CPU_Context_save_fp_context( &fp_context_ptr )
+ * void _CPU_Context_restore_fp_context( &fp_context_ptr )
+ *
+ * This section is used to context switch an i80287, i80387,
+ * the built-in coprocessor or the i80486 or compatible.
+ */
+
+.set FPCONTEXT_ARG, 4 # FP context argument
+
+ .align 2
+ PUBLIC (_CPU_Context_save_fp)
+SYM (_CPU_Context_save_fp):
+ movl FPCONTEXT_ARG(esp),eax # eax = &ptr to FP context area
+ movl (eax),eax # eax = FP context area
+ fsave (eax) # save FP context
+ ret
+
+ .align 2
+ PUBLIC (_CPU_Context_restore_fp)
+SYM (_CPU_Context_restore_fp):
+ movl FPCONTEXT_ARG(esp),eax # eax = &ptr to FP context area
+ movl (eax),eax # eax = FP context area
+ frstor (eax) # restore FP context
+ ret
+
+/*PAGE
+ * void _ISR_Handler()
+ *
+ * This routine provides the RTEMS interrupt management.
+ *
+ * NOTE:
+ * Upon entry, the stack will contain a stack frame back to the
+ * interrupted task. If dispatching is enabled, this is the
+ * outer most interrupt, and (a context switch is necessary or
+ * the current task has signals), then set up the stack to
+ * transfer control to the interrupt dispatcher.
+ */
+
+.set SET_SEGMENT_REGISTERS_IN_INTERRUPT, 0
+
+.set SAVED_REGS , 32 # space consumed by saved regs
+.set EIP_OFFSET , SAVED_REGS # offset of tasks eip
+.set CS_OFFSET , EIP_OFFSET+4 # offset of tasks code segment
+.set EFLAGS_OFFSET , CS_OFFSET+4 # offset of tasks eflags
+
+ .align 2
+ PUBLIC (_ISR_Handler)
+
+SYM (_ISR_Handler):
+ /*
+ * Before this was point is reached the vectors unique
+ * entry point did the following:
+ *
+ * 1. saved all registers with a "pusha"
+ * 2. put the vector number in eax.
+ *
+ * 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
+ */
+
+ movl esp, edx # edx = previous stack pointer
+ cmpl $0, SYM (_ISR_Nest_level) # is this the outermost interrupt?
+ jne nested # No, then continue
+ movl 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:
+ pushl edx # save the previous stack pointer
+ incl SYM (_ISR_Nest_level) # one nest level deeper
+ incl SYM (_Thread_Dispatch_disable_level) # disable multitasking
+
+ # EAX is preloaded with the vector number.
+ push eax # push vector number
+ mov SYM (_ISR_Vector_table) (,eax,4),eax
+ # eax = Users handler
+ call eax # invoke user ISR
+ pop eax # eax = vector number
+
+ decl SYM (_ISR_Nest_level) # one less ISR nest level
+ # If interrupts are nested,
+ # then dispatching is disabled
+
+ decl SYM (_Thread_Dispatch_disable_level)
+ # unnest multitasking
+ # Is dispatch disabled
+ jne exit # Yes, then exit
+
+ cmpl $0, SYM (_Context_Switch_necessary)
+ # Is task switch necessary?
+ jne bframe # Yes, then build stack
+
+ cmpl $0, SYM (_ISR_Signals_to_thread_executing)
+ # signals sent to Run_thread
+ # while in interrupt handler?
+ je exit # No, exit
+
+bframe:
+ cli # DISABLE INTERRUPTS!!
+ popl esp # restore the stack pointer
+ movl $0, SYM (_ISR_Signals_to_thread_executing)
+ # push the isf for Isr_dispatch
+ push EFLAGS_OFFSET(esp) # push tasks eflags
+ push cs # cs of Isr_dispatch
+ push $ SYM (_ISR_Dispatch) # entry point
+ iret
+
+exit:
+ cli # DISABLE INTERRUPTS!!
+ popl esp # restore the stack pointer
+
+ /*
+ * 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
+ */
+
+ popa # restore general registers
+ iret
+
+/*PAGE
+ * Distinct Interrupt Entry Points
+ *
+ * The following macro and the 256 instantiations of the macro
+ * are necessary to determine which interrupt vector occurred.
+ * The following macro allows a unique entry point to be defined
+ * for each vector.
+ *
+ * NOTE: There are not spaces around the vector number argument
+ * to the DISTINCT_INTERRUPT_ENTRY macro because m4 will
+ * undesirably generate the symbol "_Isr_handler_ N"
+ * instead of "_Isr_handler_N" like we want.
+ */
+
+#define DISTINCT_INTERRUPT_ENTRY(_vector) \
+ .align 16 ; \
+ PUBLIC (_ISR_Handler_ ## _vector ) ; \
+SYM (_ISR_Handler_ ## _vector ): \
+ pusha ; \
+ xor eax, eax ; \
+ movb $ ## _vector, al ; \
+ 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)
+DISTINCT_INTERRUPT_ENTRY(16)
+DISTINCT_INTERRUPT_ENTRY(17)
+DISTINCT_INTERRUPT_ENTRY(18)
+DISTINCT_INTERRUPT_ENTRY(19)
+DISTINCT_INTERRUPT_ENTRY(20)
+DISTINCT_INTERRUPT_ENTRY(21)
+DISTINCT_INTERRUPT_ENTRY(22)
+DISTINCT_INTERRUPT_ENTRY(23)
+DISTINCT_INTERRUPT_ENTRY(24)
+DISTINCT_INTERRUPT_ENTRY(25)
+DISTINCT_INTERRUPT_ENTRY(26)
+DISTINCT_INTERRUPT_ENTRY(27)
+DISTINCT_INTERRUPT_ENTRY(28)
+DISTINCT_INTERRUPT_ENTRY(29)
+DISTINCT_INTERRUPT_ENTRY(30)
+DISTINCT_INTERRUPT_ENTRY(31)
+DISTINCT_INTERRUPT_ENTRY(32)
+DISTINCT_INTERRUPT_ENTRY(33)
+DISTINCT_INTERRUPT_ENTRY(34)
+DISTINCT_INTERRUPT_ENTRY(35)
+DISTINCT_INTERRUPT_ENTRY(36)
+DISTINCT_INTERRUPT_ENTRY(37)
+DISTINCT_INTERRUPT_ENTRY(38)
+DISTINCT_INTERRUPT_ENTRY(39)
+DISTINCT_INTERRUPT_ENTRY(40)
+DISTINCT_INTERRUPT_ENTRY(41)
+DISTINCT_INTERRUPT_ENTRY(42)
+DISTINCT_INTERRUPT_ENTRY(43)
+DISTINCT_INTERRUPT_ENTRY(44)
+DISTINCT_INTERRUPT_ENTRY(45)
+DISTINCT_INTERRUPT_ENTRY(46)
+DISTINCT_INTERRUPT_ENTRY(47)
+DISTINCT_INTERRUPT_ENTRY(48)
+DISTINCT_INTERRUPT_ENTRY(49)
+DISTINCT_INTERRUPT_ENTRY(50)
+DISTINCT_INTERRUPT_ENTRY(51)
+DISTINCT_INTERRUPT_ENTRY(52)
+DISTINCT_INTERRUPT_ENTRY(53)
+DISTINCT_INTERRUPT_ENTRY(54)
+DISTINCT_INTERRUPT_ENTRY(55)
+DISTINCT_INTERRUPT_ENTRY(56)
+DISTINCT_INTERRUPT_ENTRY(57)
+DISTINCT_INTERRUPT_ENTRY(58)
+DISTINCT_INTERRUPT_ENTRY(59)
+DISTINCT_INTERRUPT_ENTRY(60)
+DISTINCT_INTERRUPT_ENTRY(61)
+DISTINCT_INTERRUPT_ENTRY(62)
+DISTINCT_INTERRUPT_ENTRY(63)
+DISTINCT_INTERRUPT_ENTRY(64)
+DISTINCT_INTERRUPT_ENTRY(65)
+DISTINCT_INTERRUPT_ENTRY(66)
+DISTINCT_INTERRUPT_ENTRY(67)
+DISTINCT_INTERRUPT_ENTRY(68)
+DISTINCT_INTERRUPT_ENTRY(69)
+DISTINCT_INTERRUPT_ENTRY(70)
+DISTINCT_INTERRUPT_ENTRY(71)
+DISTINCT_INTERRUPT_ENTRY(72)
+DISTINCT_INTERRUPT_ENTRY(73)
+DISTINCT_INTERRUPT_ENTRY(74)
+DISTINCT_INTERRUPT_ENTRY(75)
+DISTINCT_INTERRUPT_ENTRY(76)
+DISTINCT_INTERRUPT_ENTRY(77)
+DISTINCT_INTERRUPT_ENTRY(78)
+DISTINCT_INTERRUPT_ENTRY(79)
+DISTINCT_INTERRUPT_ENTRY(80)
+DISTINCT_INTERRUPT_ENTRY(81)
+DISTINCT_INTERRUPT_ENTRY(82)
+DISTINCT_INTERRUPT_ENTRY(83)
+DISTINCT_INTERRUPT_ENTRY(84)
+DISTINCT_INTERRUPT_ENTRY(85)
+DISTINCT_INTERRUPT_ENTRY(86)
+DISTINCT_INTERRUPT_ENTRY(87)
+DISTINCT_INTERRUPT_ENTRY(88)
+DISTINCT_INTERRUPT_ENTRY(89)
+DISTINCT_INTERRUPT_ENTRY(90)
+DISTINCT_INTERRUPT_ENTRY(91)
+DISTINCT_INTERRUPT_ENTRY(92)
+DISTINCT_INTERRUPT_ENTRY(93)
+DISTINCT_INTERRUPT_ENTRY(94)
+DISTINCT_INTERRUPT_ENTRY(95)
+DISTINCT_INTERRUPT_ENTRY(96)
+DISTINCT_INTERRUPT_ENTRY(97)
+DISTINCT_INTERRUPT_ENTRY(98)
+DISTINCT_INTERRUPT_ENTRY(99)
+DISTINCT_INTERRUPT_ENTRY(100)
+DISTINCT_INTERRUPT_ENTRY(101)
+DISTINCT_INTERRUPT_ENTRY(102)
+DISTINCT_INTERRUPT_ENTRY(103)
+DISTINCT_INTERRUPT_ENTRY(104)
+DISTINCT_INTERRUPT_ENTRY(105)
+DISTINCT_INTERRUPT_ENTRY(106)
+DISTINCT_INTERRUPT_ENTRY(107)
+DISTINCT_INTERRUPT_ENTRY(108)
+DISTINCT_INTERRUPT_ENTRY(109)
+DISTINCT_INTERRUPT_ENTRY(110)
+DISTINCT_INTERRUPT_ENTRY(111)
+DISTINCT_INTERRUPT_ENTRY(112)
+DISTINCT_INTERRUPT_ENTRY(113)
+DISTINCT_INTERRUPT_ENTRY(114)
+DISTINCT_INTERRUPT_ENTRY(115)
+DISTINCT_INTERRUPT_ENTRY(116)
+DISTINCT_INTERRUPT_ENTRY(117)
+DISTINCT_INTERRUPT_ENTRY(118)
+DISTINCT_INTERRUPT_ENTRY(119)
+DISTINCT_INTERRUPT_ENTRY(120)
+DISTINCT_INTERRUPT_ENTRY(121)
+DISTINCT_INTERRUPT_ENTRY(122)
+DISTINCT_INTERRUPT_ENTRY(123)
+DISTINCT_INTERRUPT_ENTRY(124)
+DISTINCT_INTERRUPT_ENTRY(125)
+DISTINCT_INTERRUPT_ENTRY(126)
+DISTINCT_INTERRUPT_ENTRY(127)
+DISTINCT_INTERRUPT_ENTRY(128)
+DISTINCT_INTERRUPT_ENTRY(129)
+DISTINCT_INTERRUPT_ENTRY(130)
+DISTINCT_INTERRUPT_ENTRY(131)
+DISTINCT_INTERRUPT_ENTRY(132)
+DISTINCT_INTERRUPT_ENTRY(133)
+DISTINCT_INTERRUPT_ENTRY(134)
+DISTINCT_INTERRUPT_ENTRY(135)
+DISTINCT_INTERRUPT_ENTRY(136)
+DISTINCT_INTERRUPT_ENTRY(137)
+DISTINCT_INTERRUPT_ENTRY(138)
+DISTINCT_INTERRUPT_ENTRY(139)
+DISTINCT_INTERRUPT_ENTRY(140)
+DISTINCT_INTERRUPT_ENTRY(141)
+DISTINCT_INTERRUPT_ENTRY(142)
+DISTINCT_INTERRUPT_ENTRY(143)
+DISTINCT_INTERRUPT_ENTRY(144)
+DISTINCT_INTERRUPT_ENTRY(145)
+DISTINCT_INTERRUPT_ENTRY(146)
+DISTINCT_INTERRUPT_ENTRY(147)
+DISTINCT_INTERRUPT_ENTRY(148)
+DISTINCT_INTERRUPT_ENTRY(149)
+DISTINCT_INTERRUPT_ENTRY(150)
+DISTINCT_INTERRUPT_ENTRY(151)
+DISTINCT_INTERRUPT_ENTRY(152)
+DISTINCT_INTERRUPT_ENTRY(153)
+DISTINCT_INTERRUPT_ENTRY(154)
+DISTINCT_INTERRUPT_ENTRY(155)
+DISTINCT_INTERRUPT_ENTRY(156)
+DISTINCT_INTERRUPT_ENTRY(157)
+DISTINCT_INTERRUPT_ENTRY(158)
+DISTINCT_INTERRUPT_ENTRY(159)
+DISTINCT_INTERRUPT_ENTRY(160)
+DISTINCT_INTERRUPT_ENTRY(161)
+DISTINCT_INTERRUPT_ENTRY(162)
+DISTINCT_INTERRUPT_ENTRY(163)
+DISTINCT_INTERRUPT_ENTRY(164)
+DISTINCT_INTERRUPT_ENTRY(165)
+DISTINCT_INTERRUPT_ENTRY(166)
+DISTINCT_INTERRUPT_ENTRY(167)
+DISTINCT_INTERRUPT_ENTRY(168)
+DISTINCT_INTERRUPT_ENTRY(169)
+DISTINCT_INTERRUPT_ENTRY(170)
+DISTINCT_INTERRUPT_ENTRY(171)
+DISTINCT_INTERRUPT_ENTRY(172)
+DISTINCT_INTERRUPT_ENTRY(173)
+DISTINCT_INTERRUPT_ENTRY(174)
+DISTINCT_INTERRUPT_ENTRY(175)
+DISTINCT_INTERRUPT_ENTRY(176)
+DISTINCT_INTERRUPT_ENTRY(177)
+DISTINCT_INTERRUPT_ENTRY(178)
+DISTINCT_INTERRUPT_ENTRY(179)
+DISTINCT_INTERRUPT_ENTRY(180)
+DISTINCT_INTERRUPT_ENTRY(181)
+DISTINCT_INTERRUPT_ENTRY(182)
+DISTINCT_INTERRUPT_ENTRY(183)
+DISTINCT_INTERRUPT_ENTRY(184)
+DISTINCT_INTERRUPT_ENTRY(185)
+DISTINCT_INTERRUPT_ENTRY(186)
+DISTINCT_INTERRUPT_ENTRY(187)
+DISTINCT_INTERRUPT_ENTRY(188)
+DISTINCT_INTERRUPT_ENTRY(189)
+DISTINCT_INTERRUPT_ENTRY(190)
+DISTINCT_INTERRUPT_ENTRY(191)
+DISTINCT_INTERRUPT_ENTRY(192)
+DISTINCT_INTERRUPT_ENTRY(193)
+DISTINCT_INTERRUPT_ENTRY(194)
+DISTINCT_INTERRUPT_ENTRY(195)
+DISTINCT_INTERRUPT_ENTRY(196)
+DISTINCT_INTERRUPT_ENTRY(197)
+DISTINCT_INTERRUPT_ENTRY(198)
+DISTINCT_INTERRUPT_ENTRY(199)
+DISTINCT_INTERRUPT_ENTRY(200)
+DISTINCT_INTERRUPT_ENTRY(201)
+DISTINCT_INTERRUPT_ENTRY(202)
+DISTINCT_INTERRUPT_ENTRY(203)
+DISTINCT_INTERRUPT_ENTRY(204)
+DISTINCT_INTERRUPT_ENTRY(205)
+DISTINCT_INTERRUPT_ENTRY(206)
+DISTINCT_INTERRUPT_ENTRY(207)
+DISTINCT_INTERRUPT_ENTRY(208)
+DISTINCT_INTERRUPT_ENTRY(209)
+DISTINCT_INTERRUPT_ENTRY(210)
+DISTINCT_INTERRUPT_ENTRY(211)
+DISTINCT_INTERRUPT_ENTRY(212)
+DISTINCT_INTERRUPT_ENTRY(213)
+DISTINCT_INTERRUPT_ENTRY(214)
+DISTINCT_INTERRUPT_ENTRY(215)
+DISTINCT_INTERRUPT_ENTRY(216)
+DISTINCT_INTERRUPT_ENTRY(217)
+DISTINCT_INTERRUPT_ENTRY(218)
+DISTINCT_INTERRUPT_ENTRY(219)
+DISTINCT_INTERRUPT_ENTRY(220)
+DISTINCT_INTERRUPT_ENTRY(221)
+DISTINCT_INTERRUPT_ENTRY(222)
+DISTINCT_INTERRUPT_ENTRY(223)
+DISTINCT_INTERRUPT_ENTRY(224)
+DISTINCT_INTERRUPT_ENTRY(225)
+DISTINCT_INTERRUPT_ENTRY(226)
+DISTINCT_INTERRUPT_ENTRY(227)
+DISTINCT_INTERRUPT_ENTRY(228)
+DISTINCT_INTERRUPT_ENTRY(229)
+DISTINCT_INTERRUPT_ENTRY(230)
+DISTINCT_INTERRUPT_ENTRY(231)
+DISTINCT_INTERRUPT_ENTRY(232)
+DISTINCT_INTERRUPT_ENTRY(233)
+DISTINCT_INTERRUPT_ENTRY(234)
+DISTINCT_INTERRUPT_ENTRY(235)
+DISTINCT_INTERRUPT_ENTRY(236)
+DISTINCT_INTERRUPT_ENTRY(237)
+DISTINCT_INTERRUPT_ENTRY(238)
+DISTINCT_INTERRUPT_ENTRY(239)
+DISTINCT_INTERRUPT_ENTRY(240)
+DISTINCT_INTERRUPT_ENTRY(241)
+DISTINCT_INTERRUPT_ENTRY(242)
+DISTINCT_INTERRUPT_ENTRY(243)
+DISTINCT_INTERRUPT_ENTRY(244)
+DISTINCT_INTERRUPT_ENTRY(245)
+DISTINCT_INTERRUPT_ENTRY(246)
+DISTINCT_INTERRUPT_ENTRY(247)
+DISTINCT_INTERRUPT_ENTRY(248)
+DISTINCT_INTERRUPT_ENTRY(249)
+DISTINCT_INTERRUPT_ENTRY(250)
+DISTINCT_INTERRUPT_ENTRY(251)
+DISTINCT_INTERRUPT_ENTRY(252)
+DISTINCT_INTERRUPT_ENTRY(253)
+DISTINCT_INTERRUPT_ENTRY(254)
+DISTINCT_INTERRUPT_ENTRY(255)
+
+/*PAGE
+ * void _ISR_Dispatch()
+ *
+ * Entry point from the outermost interrupt service routine exit.
+ * The current stack is the supervisor mode stack.
+ */
+
+ PUBLIC (_ISR_Dispatch)
+SYM (_ISR_Dispatch):
+
+ call SYM (_Thread_Dispatch) # invoke Dispatcher
+
+ /*
+ * 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
+ */
+
+ popa # restore general registers
+ iret # return to interrupted thread
+
+/*PAGE
+ *
+ * void i386_Install_idt(
+ * unsigned32 source_offset,
+ * unsigned16 destination_segment,
+ * unsigned32 destination_offset
+ * );
+ */
+
+ .align 2
+ PUBLIC (i386_Install_idt)
+
+.set INSTALL_IDT_SAVED_REGS, 8
+
+.set SOURCE_OFFSET_ARG, INSTALL_IDT_SAVED_REGS + 4
+.set DESTINATION_SEGMENT_ARG, INSTALL_IDT_SAVED_REGS + 8
+.set DESTINATION_OFFSET_ARG, INSTALL_IDT_SAVED_REGS + 12
+
+SYM (i386_Install_idt):
+ push esi
+ push edi
+
+ movl SOURCE_OFFSET_ARG(esp),esi
+ movl DESTINATION_OFFSET_ARG(esp),edi
+
+ pushf # save flags
+ cli # DISABLE INTERRUPTS!!!
+
+ movw DESTINATION_SEGMENT_ARG+4(esp),ax
+ push es # save es
+ movw ax,es
+ movsl # copy 1st half of IDT entry
+ movsl # copy 2nd half of IDT entry
+ pop es # restore es
+
+ popf # ENABLE INTERRUPTS!!!
+
+ pop edi
+ pop esi
+ ret
+
+/*
+ * void *i386_Logical_to_physical(
+ * rtems_unsigned16 segment,
+ * void *address
+ * );
+ *
+ * Returns thirty-two bit physical address for segment:address.
+ */
+
+.set SEGMENT_ARG, 4
+.set ADDRESS_ARG, 8
+
+ PUBLIC (i386_Logical_to_physical)
+
+SYM (i386_Logical_to_physical):
+
+ xorl eax,eax # clear eax
+ movzwl SEGMENT_ARG(esp),ecx # ecx = segment value
+ movl $ SYM (_Global_descriptor_table),edx
+ # edx = address of our GDT
+ addl ecx,edx # edx = address of desired entry
+ movb 7(edx),ah # ah = base 31:24
+ movb 4(edx),al # al = base 23:16
+ shll $16,eax # move ax into correct bits
+ movw 2(edx),ax # ax = base 0:15
+ movl ADDRESS_ARG(esp),ecx # ecx = address to convert
+ addl eax,ecx # ecx = physical address equivalent
+ movl ecx,eax # eax = ecx
+ ret
+
+/*
+ * void *i386_Physical_to_logical(
+ * rtems_unsigned16 segment,
+ * void *address
+ * );
+ *
+ * Returns thirty-two bit physical address for segment:address.
+ */
+
+/*
+ *.set SEGMENT_ARG, 4
+ *.set ADDRESS_ARG, 8 -- use sets from above
+ */
+
+ PUBLIC (i386_Physical_to_logical)
+
+SYM (i386_Physical_to_logical):
+ xorl eax,eax # clear eax
+ movzwl SEGMENT_ARG(esp),ecx # ecx = segment value
+ movl $ SYM (_Global_descriptor_table),edx
+ # edx = address of our GDT
+ addl ecx,edx # edx = address of desired entry
+ movb 7(edx),ah # ah = base 31:24
+ movb 4(edx),al # al = base 23:16
+ shll $16,eax # move ax into correct bits
+ movw 2(edx),ax # ax = base 0:15
+ movl ADDRESS_ARG(esp),ecx # ecx = address to convert
+ subl eax,ecx # ecx = logical address equivalent
+ movl ecx,eax # eax = ecx
+ ret
+
+END_CODE
+
+END