diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 1995-05-11 17:39:37 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 1995-05-11 17:39:37 +0000 |
commit | ac7d5ef06a6d6e8d84abbd1f0b82162725f98326 (patch) | |
tree | 9304cf759a73f2a1c6fd3191948f00e870af3787 /c/src/exec/score/cpu/i386/cpu_asm.s | |
download | rtems-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.s | 654 |
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 |